tags:

views:

32

answers:

2

I'm using Hash::Util's lock_keys to die whenever trying to access a non-existing key in a hash.

  1. Sometimes my hashes are deep (hash of hashes of hashes...). Is there a quick method to lock them all at once?

  2. Is it possible to control the default message upon failure (i.e. add a Dump of the hash in which the key wasn't found)

A: 
  1. lock_hash_recurse

  2. Catch the exception, then dump as you wish and rethrow.


use Try::Tiny;
try {
    $hash{key} = 123; # illegal modification
} catch {
    use DDS; DumpLex \%hash;
    die $_;
}
daxim
You would have to wrap every hash lookup, that may not be feasible.
Chas. Owens
`use Hash::Util qw(lock_hash_recurse unlock_hash_recurse)` gives me `"lock_hash_recurse" is not exported by the Hash::Util module "unlock_hash_recurse" is not exported by the Hash::Util module` ???
David B
The function is not exportable. Say the full name: `Hash::Util::lock_hash_recurse …`
daxim
I just replaced some `lock_keys` with `lock_hash_recurse` and now I get errors: `Use of uninitialized value in string eq at /usr/lib/perl/5.10/Hash/Util.pm line 153.`
David B
[Open a new question](http://stackoverflow.com/questions/ask), and there provide the data you work with.
daxim
See http://stackoverflow.com/questions/3727619/how-do-i-use-lock-hash-recurse-in-perl
David B
+1  A: 

Question 2 is possible, but you are at the whims of the Hash::Util author(s):

#!/usr/bin/perl

use strict;
use warnings;

use Hash::Util qw/lock_keys/;

$SIG{__DIE__} = sub {
    my $message = shift;
    return unless my ($key, $file, $line) = $message =~ m{
        Attempt [ ] to [ ] access [ ] disallowed [ ] key [ ] '(.*?)'
        [ ] in [ ] a [ ] restricted [ ] hash [ ] at [ ] (.*?) [ ]
        line [ ] (.*?).
    }x;
    die "$key doesn't exist at $file line $line.\n";
};

my %h = map { $_ => undef } "a" .. "z";
lock_keys %h;

my $s = $h{4};
Chas. Owens