[Phoenix-pm] Multi-level hash - quick key reference?

Scott Walters scott at illogics.org
Wed Jun 7 16:11:16 PDT 2006


Hey Bobby,

I can try to track this down if you like, but xmath has a patch to Perl that modifies
the grammar to recogize ` as something like . in JavaScript, so you can write 
$hash`foo`bar`baz to mean $hash{foo}{bar}{baz}.  Matching braces are tedious to type.

Data::Alias is nice for making little shortcuts, too:

use Data::Alias;
alias my $bucket = $hash{foo}{bar}{baz}{quux};
$bucket = 20;
print $hash{foo}{bar}{baz}{quux}, "\n"; # 20

If you are designing the datastructure from the beginning, there's the old Perl 4
multidim syntax:

$hash{'foo', 'bar', 'baz', 'quux'} = 20;
$hash{(qw/foo bar baz quux/)} = 20;

That's not the same thing as writing $hash{foo}{bar}{baz}{quux} but if the
keys don't contain binary data and you don't need to list the keys at a
given depth, it's about as useful.

You could also write an lvalue 'dehash' method using Data::Alias:

use Data::Alias;

sub dehash (\%;@) :lvalue {
    my $ref = $_[0];
    for my $i (1..$#_) {
        $ref ||= { }; #manualvivicate
        alias $ref = $ref->{$i};
    }
    $ref;
}

my %hash;
dehash(%hash, qw/foo bar baz/) = 10;
print dehash(%hash, qw/foo bar baz/), "\n";

lvalue assignments to a scalar that's aliased and Perl doesn't dump core.  W00t!

-scott

On  0, "Metz, Bobby W, WWCS" <bwmetz at att.com> wrote:
> All,
> 	I'm looking for a quicker method of accessing elements in a multi-level hash.  For example, the hash will have values like so
> 
> $hash{1}{2}{3} = "Hello World";
> $hash{1}{3}{4}{5} = "the quick brown fox";
> 
> The input to the program comes from another I can't control which will ouput values like so:
> 
> .1.2.3<tab>Hello World
> .1.3.4.5<tab>the quick brown fox
> 
> Parsing the values is cake, but what I'm looking for is a faster way to get values in/out of the hash using the ".1.2.3".  Is there some method that allows for arbitrary hash levels without coding using for loops?  I mean clearly recursion would solve this but I was hoping there was something more simple.  Or is recursion the only answer.  I was hoping for something like this, but I know this example doesn't work.  I've searched for a bit but I must be asking the right questions of mighty google.
> 
> $index = ".1.2.3";
> $index =~ s/^\.//g;
> $index =~ s/\./}{/g;
> print $hash{$index} . "\n";
> 
> Thoughts?
> 
> Thanks,
> 
> Bobby
> _______________________________________________
> Phoenix-pm mailing list
> Phoenix-pm at pm.org
> http://mail.pm.org/mailman/listinfo/phoenix-pm


More information about the Phoenix-pm mailing list