Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

strict and hashrefs

by danmcb (Monk)
on Nov 17, 2009 at 15:49 UTC ( [id://807716]=perlquestion: print w/replies, xml ) Need Help??

danmcb has asked for the wisdom of the Perl Monks concerning the following question:

It would be nice if there was a way to prevent the following typo-style errors for hashrefs, as 'strict' does for vars:

my $href = { key1 => 'foo' }; . . . if ( $href->{key_1} eq 'foo' ) { # celebrate wildly }

Of course, one could use 'defined' to tighten up the code. But it would be nice to stop hashrefs being accidentally abused somehow. As far as I know though, this is not really possible in a strict-like way, only on an ad-hoc basis. Any thoughts?

Replies are listed 'Best First'.
Re: strict and hashrefs
by moritz (Cardinal) on Nov 17, 2009 at 15:54 UTC
    It won't check at compile time, but maybe some features in Hash::Util might be useful to you?
Re: strict and hashrefs
by kennethk (Abbot) on Nov 17, 2009 at 16:18 UTC
    Since hash keys are strings, the question is really how can you avoid one-off errors when a string appears multiple times in a piece of code. Two solutions occur to me:

    1. At the head of your code you could predeclare all your desired keys, either in an array or a series of scalars. In that way, you could directly harness strict to keep your keys in line.
    2. A solution I think is a bit more elegant would be using constants to assign your allowed keys at start. Something like:

      #!/usr/bin/perl use strict; use warnings; use constant {KEY_1 => 0, KEY_2 => 1}; my %hash = (KEY_1() => 5, KEY_2, 7); print $hash{KEY_1()}; print @hash{KEY_1, KEY_2};

      Note that constants are really subroutines (Thanks for the CB help tye), so trying to access them using $hash{KEY_1} will fail, though you could build in a little resilience by making the value of KEY_1 equal to 'KEY_1'.

Re: strict and hashrefs
by JadeNB (Chaplain) on Nov 17, 2009 at 17:47 UTC

    Maybe I'm way off base, but it seems to me that a hash that only allows members of a known-at-compile-time list of keys is just an array with named indices, and would be better treated as such. This is much in line with kennethk's suggestion, except for the slight speed boost of using an array in the place of a hash. On the other hand, kennethk's solution allows a nice mix of compile-time checking and run-time flexibility:

    use constant { COMPILE_KEY => 'compile_key' }; use strict; my %hash = ( COMPILE_KEY() => 'yay', runtime_key => 'still OK' ); $hash{COMPLIE_KEY()}; # sadness

    Finally, if you don't care about speed, then Tie::StrictHash is designed to do exactly what you want, via (obviously) tieing.

    UPDATE: Of course, now that I think about it, Tie::StrictHash obviously can't do any compile-time checking, so you're probably better with the non-tie-based Hash::Util that moritz recommended.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://807716]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-25 09:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found