Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

prevent stringification for hash-keys

by morgon (Priest)
on Feb 16, 2019 at 23:16 UTC ( [id://1230007] : perlquestion . print w/replies, xml ) Need Help??

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


Sorry for being too lazy to read the documentation, I am sure I would find my answer here...

But I just spend 15 minutes (or more) on a bug where I wrote

if($hash{key}) {
where I should have written
if($hash{$key}) {
so my problem is the automatic stringification of hash-keys that prevents such a but to be discovered at compile-time.

Plenty of times this is exactly what I want, but sometimes (as here) it can conceal bugs - so is there a way to turn it off, so that accessing a hash-element via bareword would be a compiliation error?

I am sure there is...

Many thanks!

Replies are listed 'Best First'.
Re: prevent stringification for hash-keys
by tobyink (Canon) on Feb 17, 2019 at 01:11 UTC

      Heheh yes tobyink I thought about that too, but the OP appears to want to forbid in code the use of a string as a hash key, whether quoted or not, and only allow using a declared variable. IIUC.

      The way forward always starts with a minimal test.
        No, he wants to avoid stringification of hash keys, especially of barewords.
Re: prevent stringification for hash-keys
by 1nickt (Canon) on Feb 16, 2019 at 23:47 UTC

    See the core module Hash::Util.

    use strict; use warnings; use Hash::Util 'lock_keys'; my $key = 'foo'; lock_keys my %hash, ($key, 'bar'); $hash{$key}++; $hash{'key'}++; __END__
    $ perl Attempt to access disallowed key 'key' in a restricted hash at 1230007 line 11.

    Hope this helps!

    The way forward always starts with a minimal test.
      That's sort of a solution, but I still would need to explicitely call lock_keys on every hash I use.

      What I really want is a way to make $hash{bare_word} a compile-time error in a lexical scope...