Iam a perl newbie and need help in understanding the below piece of code.
I have a perl Hash defined like this
1 my %myFavourite = ("Apple"=>"Apple");
2 my @fruits = ("Apple", "Orange", "Grape");
3 @myFavourite{@fruits}; # This returns Apple. But how?
It would be great if perl gurus could explain wha开发者_如何学Ct's going on in Line-3 of the above code. myFavourite is declared has a hash,but used as an array? And the statement simply takes the key of the hash ,greps it in to the array and returns the hash values corresponding the key searched. Is this the way we grep Hash Keys in to the Array?
It doesn't return Apple. It evaluates to a hash slice consisting of all of the values in the hash corresponding to the keys in @fruits
. Notice if you turn on warnings that you get 2 warnings about uninitialized values. This is because myFavourite
does not contain values for the keys Orange
and Grape
. Look up 'hash slice' in perldata.
Essentially, @myFavourite{@fruits}
is shorthand for ($myFavourite{Apple}, $myFavourite{Orange}, $myFavourite{Grape})
, which in this case is ($myFavourite{Apple},undef,undef)
. If you print it, the only output you see is Apple
.
myFavourite is declared has a hash,but used as an array?
Yes, and it returns a list. It's a hash slice. See: http://perldoc.perl.org/perldata.html
Think of it as an expansion of array @fruits into multiple hash key lookups. The @hash{@keys} syntax is just a handy way of extracting portions of the hash.
Specifically:
@myFavourite{@fruits}
is equivalent to:
($myFavourite{'Apple'},$myFavourite{'Orange'},$myFavourite{'Grape'})
which returns a three item list if called in list context or a concatenation of all three elements in scalar context (e.g. print)
my @slice_values = @myFavourite{@fruits}
# @slice_values now contains ('Apple',undef,undef)
# which is functionally equivalent to:
my @slice_values = map { $myFavourite{$_} } @fruits;
If you want to only extract hash values with keys, do:
my @favourite_fruits = @myFavourite{ grep { exists $myFavourite{$_} } @fruits };
# @favourite_fruits now contains ('Apple')
If you:
use warnings;
you'll see the interpreters warnings about the two uninitialized values being autovivified as undef.
精彩评论