Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Non-deprecated way to access multi-level hashes

by carcassonne (Pilgrim)
on Mar 07, 2006 at 15:03 UTC ( [id://534935]=perlquestion: print w/replies, xml ) Need Help??

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

Monks,

This works but Perl warns it's deprecated:

push @Names, %names->{$_}{realname} foreach (keys %names);

This provokes a compile error:

push @Names, %names{$_}{realname} foreach (keys %names);

So: what's the proper use ? - Thanks !

Here's the full context:

my @Names; my %names = ( 'Thunder' => { realname => "Mario", }, 'Storm' => { realname => "Alfredo", }, 'Grail' => { realname => "Giuseppe", }, );

Replies are listed 'Best First'.
Re: Non-deprecated way to access multi-level hashes
by ikegami (Patriarch) on Mar 07, 2006 at 15:10 UTC
    push @Names, $names{$_}{realname} foreach keys %names;

    or

    push @Names, $_->{realname} foreach values %names;

    or

    my @Names = map { $_->{realname} } values %names;

    The sigil to use is the type being returned.

    %hash # The entire hash is a hash. $hash{key} # An element of the hash is a scalar.

    See the "Direct" column of this table.

Re: Non-deprecated way to access multi-level hashes
by TimToady (Parson) on Mar 07, 2006 at 15:57 UTC
    Oddly enough, this deprecated syntax is much more like how Perl 6 does it, so I wouldn't worry about it too much. It's not like you're thinking about it wrong--it's just that Perl 5 has a weird idea of how sigils interact with references. Still, it'd be nice if your program didn't spit out warning messages...
Re: Non-deprecated way to access multi-level hashes
by jkva (Chaplain) on Mar 07, 2006 at 15:13 UTC
    carcassonne :
    I'd try
    for(keys %names) { push @Names, $names{$_}{realname}; }
    Hope this helps.
Re: Non-deprecated way to access multi-level hashes
by markov (Scribe) on Mar 07, 2006 at 15:19 UTC
    use map() to slice:
     my @realnames = map { $_->{realname} } values %names;
    
      This is the most efficient solution. I wish I could recall exactly where I have read that maps() are more efficient than foreach. Perhaps in Advanced Perl Programming, or not.
Re: Non-deprecated way to access multi-level hashes
by bobf (Monsignor) on Mar 07, 2006 at 15:21 UTC

    If you're trying to get the values of the realname key into the @Names array, use map:

    my @Names = map { $names{$_}{realname} } keys %names;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://534935]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-19 15:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found