Re: strict "vars" mode for hash key literals?
by kennethk (Abbot) on Oct 18, 2016 at 15:41 UTC
|
The Hash::Util CORE module handles your use cases. They incur a run time penalty, so I usually use them in a development context only.
use Hash::Util 'lock_keys';
my %hash;
lock_keys %hash, qw/foo bar baz/; # define hash keys to use
say $hash{foo}; # ok, declared
say $hash{bah}; # compile-time error, undeclared
say $hash{$var}; # ok, not literal
See *lock_keys*.
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] |
|
Wouldn't that be a runtime error? After all, the hash isn't even locked until lock_keys is executed at runtime.
Also, I think there is no performance penalty (except to the call to lock_keys), since I believe all lock_keys does is set the read-only flag on the hash, which is checked regardless of whether you've set lock_keys or not.
| [reply] [d/l] [select] |
|
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.0;
use Hash::Util 'lock_keys';
use Benchmark 'cmpthese';
lock_keys my %hash1, qw/foo bar baz/;
my %hash2;
cmpthese(1e2, {
'lock' => sub { for (1 .. 1e5) {$hash1{foo}++;$hash1{bar}++;$
+hash1{baz}++;} },
'no_lock' => sub { for (1 .. 1e5) {$hash2{foo}++;$hash2{bar}++;$
+hash2{baz}++;} },
});
yields
Rate lock no_lock
lock 61.6/s -- -8%
no_lock 66.8/s 8% --
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
|
|
$ perl '-mfeature=say' -cw 1174218.pl
Name "main::var" used only once: possible typo at 1174218.pl line 7.
1174218.pl syntax OK
| [reply] [d/l] |
Re: strict "vars" mode for hash key literals?
by BrowserUk (Patriarch) on Oct 18, 2016 at 15:45 UTC
|
See Hash::Util for the concept of 'restricted hashes'.
That said, I don't know of anyone who has used perl for more than a few weeks that feels the need to use them; nor in the 12 or 13 years since 5.8, have I encountered any code in the wild that uses them.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
|
I use them to great effect with results fetched from an SQL query. There, locked hashes have made it very obvious when my code tries to access elements which have been renamed in the SQL query, which has reduced the time to debug these things.
But when I'm at liberty to name the hash entries myself, I don't feel the need for restricted hashes.
| [reply] |
|
While I agree that I've never encountered restricted hashes in real code, and have never felt like I should reach for them, I also cannot say that I have never been bitten by problems that they could have prevented. Unfortunately, unlike use strict, they are a feeble solution that is inelegant to wield.
| [reply] [d/l] |
|
| [reply] |
|
Re: strict "vars" mode for hash key literals?
by Eily (Monsignor) on Oct 18, 2016 at 17:18 UTC
|
++ for restricted hashes. But as pointed by ikegami, they do not catch the exception at compile time.
There might be a source filter somewhere on CPAN that does what you want, if you're ok with using a source filter. Parsing the code for /[$](\w+)[{](\w+)[}]/ and making sure that $2 is a valid key for hash $1 would probably be easy and safe enough.
Otherwise, there's the solution of using constants. Either by using an array instead of the hash:
use strict;
use warnings;
use constant {
FOO => 0,
BAR => 1,
BAZ => 2
};
$var = BAZ;
my @array;
say $array[FOO]; # OK
say $array[BAH]; # Bareword "BAH" not allowed while "strict subs" in
+use
say $array[$var]; # OK
Or never allowing the bareword interpretation for a hash key by adding a + (there's no way to disable ALL barewords is there?)
use strict;
use warnings;
use constant {
FOO => "foo",
BAR => "bar",
BAZ => "baz"
};
my %hash;
say $hash{+FOO}; # OK
say $hash{+BAH}; # Bareword "BAH" not allowed while "strict subs" in
+use
say $hash{+shift} # Bonus
| [reply] [d/l] [select] |
Re: strict "vars" mode for hash key literals?
by hippo (Bishop) on Oct 18, 2016 at 15:42 UTC
|
| [reply] |