CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Anomaly with hash reference

 



Cupidvogel
Novice

Mar 26, 2012, 2:17 AM

Post #1 of 4 (1607 views)
Anomaly with hash reference Can't Post

Hi, suppose I have a hash like this:


Code
%gilligan_info = ( 
name => 'Gilligan',
hat => 'White',
shirt => 'Red',
position => 'First Mate',
);



and an array stores the reference to this hash:


Code
@crew = (\%gilligan_info);


Now if I want to know the value of the hash corresponding to a key of name, I use


Code
print $crew[0]{'name'};


and it prints out the value. But when I first assign the array element to a scalar and then do the same thing, nothing gets printed:


Code
$foo = $crew[0]; 
print $foo{'name'}; //prints nothing


and the only way to print using the scalar is


Code
print $$foo{'name'};


Why is it so, given that $foo and $crew[0] are the same thing?


BillKSmith
Veteran

Mar 26, 2012, 10:13 AM

Post #2 of 4 (1524 views)
Re: [Cupidvogel] Anomaly with hash reference [In reply to] Can't Post

Refer to perldoc perlref (section 'Using References').

You are correct that $foo and $crew[0] are both references to the same hash. Case 2 (in the document) is messy, but it has the advantage that it can correctly dereference any reference (including both of these)


Code
print ${$crew[0]}{'name'}; 
print ${$foo }{'name'};



Your working examples are examples of other cases. They are both convenient, but you must read very carefully to be sure when they can be used.
Good Luck,
Bill


budman
User

Mar 26, 2012, 2:57 PM

Post #3 of 4 (1461 views)
Re: [Cupidvogel] Anomaly with hash reference [In reply to] Can't Post


Quote
Why is it so, given that $foo and $crew[0] are the same thing?


Because $foo is reference, and $crew[0] is an array element.

When you place the braces { } next to $foo, it means this should be a hash %foo.

When you place braces next to an array element and the contents of the array item is a reference, Perl treats it like a sequence of references (multi dimensional array). The -> arrow is optional when items are references.


$crew[0] is actually a reference to the array @crew index offset 0.

These are all equivalent:
$crew[0]->{name}
${$crew[0]}{name}
$crew[0]{name} (preferred)

The $foo variable is storing a Hash reference, Perl does not auto deref it.
So you need to dereference it.

These are all equivalent:
${$foo}{name}
$$foo{name}
$foo->{name} (preferred)


$crew[0]{name} is equivalent to $foo->{name}

Example: $array[0][1]{name}[3]{test} can be written
$array[0]->[1]->{name}->[3]->{test}

If $crew was an array ref to an anonymous array
$crew = [ \%gilligan_info ];

$crew->[0]{name} or $crew->[0]->{name}


Also, using braces when dereferencing is recommended.

${ } @{ } %{ }

Once you construct more complex structures, you will need to isolate the elements that need dereferencing


Code
my %clubs=("Minnow"=>{ 
crew=>[
{name=>"Skipper",hair=>"Blonde"},
{name=>"Gilligan",hair=>"Black"},
],
captain=>"Skipper",
}
);

print $clubs{Minnow}{crew}[0]{name}; // Skipper
print $clubs{Minnow}{crew}[1]{name}; // Gilligan
print $clubs{Minnow}{captain}; // Skipper
foreach my $m ( @{$clubs{Minnow}{crew}} ) {
foreach my $key (sort keys %{$m}){
print "$key: ",$m->{$key},"\n";
}
}



(This post was edited by budman on Mar 26, 2012, 3:39 PM)


BillKSmith
Veteran

Mar 26, 2012, 8:45 PM

Post #4 of 4 (1397 views)
Re: [budman] Anomaly with hash reference [In reply to] Can't Post


Quote
Because $foo is reference, and $crew[0] is an array element.



True, but...

$foo is a scalar variable

$crew[0] is an array element.

They each contain a reference to the hash %gilligan_info, which I believe is what the OP meant by


Quote
given that $foo and $crew[0] are the same thing



My code verifies this by dereferencing both of them with the same syntax. (Case 2 from the referenced document)

All of the working examples from both you and the OP are alternate syntaxes documented in the same section of the document. I usually use the case 2 syntax in my own work because it always works.
Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives