To access an element of a hash, use syntax that looks like this:
$hash{$some_key}
This is similar to what we used for array access, but here we use curly braces instead of square brackets around the subscript (key). [6] And that key expression is now a string, rather than a number:
[6] Here's a peek into the mind of Larry Wall: Larry says that we use curly braces instead of square brackets because we're doing something fancier than ordinary array access, so we should use fancier punctuation.
$family_name{"fred"} = "flintstone";
$family_name{"barney"} = "rubble";
Figure 5-2 shows how the resulting hash keys are assigned.
This lets us use code like this:
foreach $person (qw< barney fred >) {
print "I've heard of $person $family_name{$person}.\n";
}
The
When choosing the name of a hash, it's often nice to think of the word "of" between the name of the hash and the key. As in, "the family_name of fred is flintstone ". So the hash is named family_name . Then it becomes clear what the relationship is between the keys and their values.
Of course, the hash key may be any expression, not just the literal strings and simple scalar
$foo = "bar";
print $family_name{ $foo . "ney" }; # prints "rubble"
When you store something into an existing hash element, that overwrites the previous value:
$family_name{"fred"} = "astaire"; # gives new value to existing element
$bedrock = $family_name{"fred"}; # gets "astaire"; old value is lost
That's analogous to what happens with arrays and scalars; if you store something new into
$pebbles[17]
or
$dino
, the old value is
Hash elements will spring into existence by assignment:
$family_name{"wilma"} = "flintstone"; # adds a new key (and value)
$family_name{"betty"} .= $family_name{"barney"}; # creates the element if needed
That's also just like what happens with arrays and scalars; if you didn't have $pebbles[17] or $dino before, you will have it after you assign to it. If you didn't have $family_name{"betty"} before, you do now.
And accessing outside the hash gives undef :
$granite = $family_name{"larry"}; # No larry here: undef
Once again, this is just like what happens with arrays and scalars; if there's nothing yet stored in $pebbles[17] or $dino , accessing them will yield undef . If there's nothing yet stored in $family_name{"larry"} , accessing it will yield undef .
To refer to the entire hash, use the percent sign (" % ") as a prefix. So, the hash we've been using for the last few pages is actually called %family_name .
For convenience, a hash may be converted into a list, and back again. Assigning to a hash (in this case, the one from Figure 5-1 ) is a list-context assignment, where the list is made of key-value pairs: [7]
[7] Although any list expression may be used, it must have an even number of elements, because the hash is made of key-value pairs . An odd element will likely do something unreliable, although it's a warnable offense.
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye\n");
The value of the hash (in a list context) is a simple list of key-value pairs:
@any_array = %some_hash;
We call this
print "@any_array\n";
# might give something like this:
# betty bye (and a newline) wilma 1.72e+30 foo 35 2.5 hello bar 12.4
The order is jumbled because Perl keeps the key-value pairs in an order that's
Of course, even though the order of the key-value pairs is jumbled, each key "sticks" with its corresponding value in the resulting list. So, even though we don't know where the key foo will appear in the list, we know that its value, 35 , will be right after it.
It's rare to do so, but a hash may be
%new_hash = %old_hash;
This is actually more work for Perl than meets the eye. Unlike what happens in languages like Pascal or C, where such an operation would be a simple matter of copying a block of memory, Perl's data structures are more complex. So, that line of code
It's more common to transform the hash in some way, though. For example, we could make an inverse hash:
%inverse_hash = reverse %any_hash;
This takes %any_hash and unwinds it into a list of key-value pairs, making a list like ( key , value , key , value , key , value , ... ) . Then reverse turns that list end-for-end, making a list like ( value , key , value , key , value , key , ... ) . Now the keys are where the values used to be, and the values are where the keys used to be. When that's stored into %inverse_hash , we'll be able to look up a string that was a value in %any_hash —it's now a key of %inverse_hash . And the value we'll find is one that was one of the keys from %any_hash . So, we have a way to look up a "value" (now a key), and find a "key" (now a value).
Of course, you might guess (or determine from scientific principles, if you're clever) that this will work properly only if the values in the original hash were unique—
[8]
Or if you don't care that there are duplicates. For example, we could invert the
%family_name
hash (in which the keys are people's given names and values are their family
%ip_address = reverse %host_name;
Now we can look up a host name or IP address with equal ease, to find the corresponding IP address or host name.
When assigning a list to a hash, sometimes it's not obvious which elements are keys and which are values. For example, in this assignment (which we saw earlier), we humans have to count through the list, saying, "key, value, key, value...", in order to determine whether 2.5 is a key or a value:
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye\n");
Wouldn't it be nice if Perl gave us a way to pair up keys and values in that kind of a list, so that it would be easy to see which ones were which? Larry thought so, too, which is why he invented the big arrow, ( => ). [9] To Perl, it's just a different way to "spell" a comma. That is, in the Perl grammar, any time that you need a comma ( , ), you can use the big arrow instead; it's all the same to Perl. [10] So here's another way to set up the hash of last names:
[9]
Yes, there's also a
little
arrow, (
->
). It's used with references, which are an advanced topic; see the
perlreftut
and
perlref
[10] Well, there's one technical difference: any bareword (a sequence of nothing but letters, digits, and underscores not starting with a digit) to the left of the big arrow is implicitly quoted. So you can leave off the quote marks on a bareword to the left of the big arrow. You may also omit the quote marks if there's nothing but a bareword as a key inside the curly braces of a hash.
my %last_name = (# a hash may be a lexical variable
"fred" => "flintstone",
"dino" => undef,
"barney" => "rubble",
"betty" => "rubble",
);
Here, it's easy (or perhaps at least easier) to see whose name pairs with which value, even if we end up