Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Recursively walk a hash to get to an element

by merlyn (Sage)
on Mar 30, 2005 at 19:26 UTC ( #443584=snippet: print w/ replies, xml ) Need Help??

Description: The question comes up frequently:
How do I start with %myhash, and a list of keys qw(bedrock flintstone fred), and get access to the value at $myhash{bedrock}{flintstone}{fred}?
Well, you call pointer_to_element, like:
my $ref = pointer_to_element(\%myhash, qw(bedrock flintstone fred)); $$ref = 42; # set it to 42 $$ref++; # increment it print $$ref; # print it!
sub pointer_to_element {
  require List::Util;
  return List::Util::reduce(sub { \($$a->{$b}) }, \shift, @_);
}
Comment on Recursively walk a hash to get to an element
Download Code
Re: Recursively walk a hash to get to an element
by princepawn (Parson) on Mar 31, 2005 at 00:36 UTC
    That is definitely one for Higher Order Perl, Second Edition.


    Carter's compass: I know I'm on the right track when by deleting something, I'm adding functionality
Re: Recursively walk a hash to get to an element
by tlm (Prior) on Mar 31, 2005 at 02:00 UTC

    There's an typo in the code; the code block in the reduce statement should be

    { \($$a->{$b}) }
    Also, when I tried the code as given (after fixing the above typo), I got the error:
    % perl rec_walk.pl Can't call method "List::Util::reduce" on unblessed reference at rec_w +alk.pl line 9.
    Here's the full code of the script that caused that error:
    use strict; my %myhash; $myhash{bedrock}{flintstone}{fred} = 3; my $ref = pointer_to_element(\%myhash, qw(bedrock flintstone fred)); sub pointer_to_element { require List::Util; return List::Util::reduce { \($$a->{$b}) } \shift, @_; }
    I couldn't figure out why the error, so I switched the code to
    use List::Util 'reduce'; sub pointer_to_element { return reduce { \($$a->{$b}) } \shift, @_; }
    and it worked great. Tres cool.

    the lowliest monk

      The reason of the error is that reduce uses a prototype not yet seen when the return statement is compiled. It's therefore interpreted as indirect object syntax (method { STATEMENTS } LIST), being do { STATEMENTS }->method(LIST) with direct syntax. The way to fix this is to call &reduce like List::Util::reduce(sub { ... }, LIST).

      ihb

      See perltoc if you don't know which perldoc to read!

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://443584]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2015-07-05 03:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls