mishka
mishka

Reputation: 2057

perl, getting nested hash from hash

I don't understand what is wrong with this script:

%Region = (1 => {name => "nameVal"}, 2 => {name => "nameVal2"});
while(my($k, %v) = each %Region) {  
    print $k, $v{'name'}, "\n"; 
}

It doesn't print the value from the nested hash.

I tried with different commas, no effect.

perl v5.12.4, mac os

Upvotes: 0

Views: 128

Answers (2)

Miller
Miller

Reputation: 35198

Always include use strict; and use warnings; at the top of EVERY perl script.

use strict;
use warnings;

my %Region = (1 => {name => "nameVal"}, 2 => {name => "nameVal2"});
while(my($k, %v) = each %Region) {  
    print $k, $v{'name'}, "\n"; 
}

In this case, the warning would have been the following:

Reference found where even-sized list expected at scratch.pl line 5.

This is pointing out the fact that you're assigning single value, a reference, to a hash %v which expects an even-sized list, or key value pairs.

So we fix that line so it's assigning a reference to a scalar:

while(my($k, $v) = each %Region) {

You will now get the following error:

Global symbol "%v" requires explicit package name at input7.pl line 6.

There is no definition for %v, only our scalar with a reference, $v. To dereference that variable and access a value, we use the arrow operator ->

    print $k, $v->{'name'}, "\n"; 

Output is now what you desire:

2nameVal2
1nameVal

The lesson here is ALWAYS include use strict; and use warnings; at the top of every perl script. For more reasons why, check out: Why use strict and warnings?

Upvotes: 3

Patrick B.
Patrick B.

Reputation: 12333

Your nested hash is hashref - a reference to a hash - so you need to access it this way using -> to dereference.

%Region = (1 => {name => "nameVal"}, 2 => {name => "nameVal2"});
while(my($k, $v) = each %Region) {  
    print $k, $v->{'name'}, "\n"; 
}

It is a hashref because you used { } to initialize your nested hash.

Upvotes: 3

Related Questions