3

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 what'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?

1
  • One thing that help to understand this, is to understand the logic behind the change of sigil in Perl variables. A hash is defined by '%' like %myhash=(a=>1,b=>2) but when you return one element of the hash (a scalar) you change the sigil to the scalar one: $myhash{a}. But if you want to return several elements (an array) you change the sigil accordingly: @myhash{a,b}. If you have an array with @myWantedKeys=('a','b'), then you can retrieve the values of these keys with @myhash{@myWantedKeys}. Commented Oct 29, 2011 at 10:31

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

5

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.