Hashes

Hashes in Perl aren’t really that hard to understand; they’re not that much harder than understanding how a phone book works. This article introduces you to hashes, what they do, and how to use them. It is excerpted from chapter five of the book Beginning Perl, written by James Lee (Apress; ISBN: 159059391X).

We have talked about two types of data: scalars and arrays. Scalars are single pieces of infor mation, while arrays are single variables containing many different values.

Alternatively, some things are better expressed as a set of one-to-one correspondences. A phone book, for example, is a set of correspondences between addresses and phone numbers. In Perl, structures like the phone book are represented as a hash. Some people call them associative arrays because they look a bit like arrays where each element is associated with another value. Most Perl programmers find that a bit too long-winded, and end up just calling them hashes.

Comparing a hash to a phone book is helpful, but there is a slight difference in that a phone book is normally ordered—the names are sorted alphabetically. In a hash the data is totally unsorted and has no intrinsic order. In fact, it’s more like directory enquiries than a phone book, in that you can easily find out what the number is if you have the name. Someone else keeps the order for you, and you needn’t ask what the first entry is.

Here’s where a diagram helps:

A scalar is one piece of data. It’s like a single block. An array or a list is like a tower of blocks; it’s kept in order, and it’s kept together as a single unit. A hash, on the other hand, is more like the illustration above. It contains several pairs of data. The pairs are in no particular order, no pair is “first” or “top,” and they’re all scattered around the hash.

{mospagebreak title=Creating a Hash}

Just like scalar variables have a $ prefix, and arrays have a @ prefix, hashes have their own prefix—a percent sign. Again, the same naming rules apply, and the variables %hash , $hash , and @hash are all different.

One way of creating a hash variable is to assign it a list that is treated as a collection of key/value pairs:

%where = (
        "Gary"     , "Dallas",
        "Lucy"     , "Exeter",
        "Ian"      , "Reading",
        "Samantha" , "Oregon"
);

In this case, the hash could be saying that “Gary’s whereabouts is Dallas,” “Lucy lives in Exeter,” and so on. All it really does is pair Gary and Dallas, Lucy and Exeter, and so on. How the pairing is interpreted is up to you.

If we want to make the relationship, and the fact that we’re dealing with a hash, a little clearer, we can use the => operator. That’s not >= , which is greater-than-or-equal-to; the => operator acts like a “quoting comma.” That is, it’s a comma, but whatever appears on the left-hand side of it—and only the left—is treated as a double-quoted string.

%where = (
        Gary     => "Dallas",
        Lucy     => "Exeter",
        Ian      => "Reading",
        Samantha => "Oregon"
);

The scalars on the left of the arrow are called the hash keys, the scalars on the right are the values. We use the keys to look up the values.


Note  Hash keys must be unique. You cannot have more than one entry for the same name, and if you try to add a new entry with the same key as an existing entry, the old one will be overwritten. Hash values meanwhile need not be unique.


Key uniqueness is more of an advantage than a limitation. Every time the word “unique” comes into a problem, like counting the unique elements of an array, your mind should imme diately echo “Use a hash!”

Because hashes and arrays are both built from structures that look like lists, you can convert between them, from array to hash, like this:

@array = qw(Gary Dallas Lucy Exeter Ian Reading Samantha Oregon);
%where = @array;

Assigning an array to a hash will work properly only when there are an even number of elements in the array.

The hash can then be assigned back to an array like so:

@array = %where;

However, you need to be careful when converting back from a hash to an array. Hashes do not have a guaranteed order; although values will always follow keys, you cannot tell what order the keys will come in. Since hash keys are unique, however, we can be sure that %hash1 = %hash2 is guaranteed to copy a hash accurately.

{mospagebreak title=Working with Hash Values}

To look up a value in a hash, we use something similar to the index notation for arrays. However, instead of locating elements by number, we’re now locating them by name, and instead of using square brackets, we use curly braces.

Here’s a simple example of looking up details in a hash:

#!/usr/bin/perl -w
# hash.pl

use strict;

my $who = "Ian";

my %where = (
        Gary     => "Dallas",
        Lucy     => "Exeter",
        Ian      => "Reading",
        Samantha => "Oregon"
);

print "Gary lives in ", $where{Gary}, "n"; print "$who lives in $where{$who}n";

$ perl hash.pl
Gary lives in Dallas
Ian lives in Reading
$

The first thing we do in this program is set up our main hash, which tells us where people live.

my %where = (
        Gary     => "Dallas",
        Lucy     => "Exeter",
        Ian      => "Reading",
        Samantha => "Oregon"
);

Like scalars and arrays, hash variables must be declared with my() when using strict.

Now we can look up an entry in our hashes—we’ll ask “Where does Gary live?”

print "Gary lives in ", $where{Gary}, "n";

This is almost identical to looking up an array element, except for using curly braces instead of square brackets and the fact that we are now allowed to use strings to index our elements. Notice that the key Gary is not quoted within the curly braces. If the key contains no whitespace characters, it is assumed quoted within the curly braces. If the key does contain whitespace characters, then we will have to quote it.

The next line is

print "$who lives in $where{$who}n";

Just as with array elements, we need not use a literal to index the element—we can look up using a variable as well.

{mospagebreak title=Adding, Changing, and Removing Elements}

Hash entries are very much like ordinary scalar variables, except that you need not declare an individual hash key before assigning to it or using it. We can add a new person to our hash just by assigning to their hash entry:

$where{Eva} = "Uxbridge";
print "Eva lives in $where{Eva}n";

A new entry springs into existence, without any problems. We can also change the entries in a hash just by reassigning to them. Let’s move people around a little:

$where{Eva}      = "Denver";
$where{Samantha} = "California";
$where{Lucy}     = "Tokyo";
$where{Gary}     = "Las Vegas";
$where{Ian}      = "Southampton";

print "Gary lives in $where{Gary}n";

To remove an entry from a hash, you need to use the delete() function, as we do in this little variant on hash.pl :

#!/usr/bin/perl -w
# badhash.pl

use strict;

my %where = (
        Gary     => "Dallas",
        Lucy     => "Exeter",
        Ian      => "Reading",
        Samantha => "Oregon"
);

delete $where{Lucy};
print "Lucy lives in $where{Lucy}n";

You can see that here we delete Lucy’s entry in
%where before we access it, so executing this program should produce an error. Sure enough, we get

$ perl badhash.pl
Use of uninitialized value in concatenation (.) at badhash.pl line 14
Lucy lives in
$

It’s not that we haven’t initialized poor Lucy, but rather that we’ve decided to get rid of her.

Please check back for the conclusion to this article.

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort