0

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

Btuman
  • 881
  • 2
  • 9
  • 37
mishka
  • 2,027
  • 2
  • 20
  • 30

2 Answers2

3

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.

Patrick B.
  • 11,773
  • 8
  • 58
  • 101
3

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?

Community
  • 1
  • 1
Miller
  • 34,962
  • 4
  • 39
  • 60