Perl Basics   «Prev  Next»

Lesson 20Hash references
Objective Learn how to use references to hashes.

Perl Hash References

In the previous lesson you learned how to use references to arrays and anonymous arrays. In this lesson we will cover references to hashes and anonymous hashes. Creating hash references is very similar to creating array references. First consider this hash from the "Perl hashes" lesson:
  • Perl Hash Example:
    %viceprez = (
       'Franklin' => 'Henry A. Wallace',
       'Harry'    => 'Alben W. Barkley',
       'Dwight'   => 'Richard M. Nixon',
       'John'     => 'Lyndon B. Johnson', 
       'Lyndon'   => 'Hubert H. Humphrey',
       'Richard'  => 'Spiro T. Agnew',
       'Gerald'   => 'Nelson A. Rockefeller',
       'Jimmy'    => 'Walter F. Mondale',
       'Ronald'   => 'George H. Bush',
       'George'   => 'J. Dan Quayle',
       'Bill'     => 'Al Gore, Jr.',
       );
    

    You can create a reference to that hash like this:
    $hashref = \%viceprez;
    

    You now have a reference relationship just like you did with array and scalar references.


Perl Diagram containing a hash of Vice Presidents
Perl hash diagram consisting of Vice Presidents
Perl hash diagram consisting of Vice Presidents

You can dereference the hash like this:
$foo = $$hashref{'Franklin'};    # 'Henry A. Wallace'

or like this:
$foo = $hashref->{'Franklin'};   # 'Henry A. Wallace'

In fact, Perl 5 makes a special allowance for using a bareword to index a hash, just so that you can do this:

$foo = $hashref->{Franklin};     # 'Henry A. Wallace'

This is probably the most common way to do it.
For all the C programmers taking this, I have a warning that should help prevent some confusion with hashes.


Warning for C programmers

It should be noted that while this is legal:
  1. $$hashref{OTHERS}{'calvin'}
  2. $$arrayref[3][1]

may be confusing to C programmers who expect operator precedence to work differently in Perl. The truth is, the $ is not even an operator in Perl, so the comparison does not work. Rather than trying to forget everything you ever learned about C, go ahead and just use the
  1. $hashref->{OTHERS}{'calvin'} and
  2. $arrayref->[3][1] constructs.

  • Array/Hash References Versus Element References
    Recall that there is a distinction between the array as a whole and each of its constituent scalar values. The array's value maintains its own reference count, and each of its elements has its own. When you take a reference to an array, its own reference count is incremented without its elements getting affected, as shown in Figure 2.6.
    Array Hash Reference Values
    Figure 2.6. - Take a reference to an array, its own reference count is incremented without its elements getting affected

    In contrast, Figure 2.7 shows the picture when you create a reference to an element of an array or a hash.
    when you create a reference to an element of an array or a hash
    Figure 2.7 - Create a reference to an element of an array or a hash

Additional topics to look at are :


Perl Complete Reference

Anonymouns Perl Hashes

An anonymous hash can be created by using curly brackets in the same way you would use the square brackets for an anonymous array:
$hashref = { 'foo' => 'bar', 'baz' => 'boz' };

A hash can include other anonymous hashes. Notice in this example the use of barewords for the keys. It's traditional to use uppercase letters for the barewords, which can prevent some confusion for the humans who may read the code sometime in the future:
$hashref = { 
  FOO => 'bar', 
  BAZ => 'boz', 
  COUPLES => { 
     'fred' => 'wilma',
     'samson' => 'delilah',
    },
  OTHERS => {
     'calvin' => 'hobbes',
     'tom' => 'jerry',
    },
  };

Dereferencing the hashes of hashes is similar to the techniques used for arrays of arrays:
$hashref->{FOO}                # bar
$hashref->{COUPLES}{'samson'}  # delilah

Using Perl Hash Reference

Some Perl operators,
  1. each or
  2. keys
require a hash as an argument. In order to use a dereferenced reference (for example, $hashref->{COUPLES}) in these contexts you must enclose the reference in curly brackets so that the syntax is not ambiguous.
In other words, the expression:
$hashref->{OTHERS}

is a reference to an anonymous hash.
The expression:
%$hashref->{OTHERS}

proably will not do what you expect, because the % binds to the $ and tries to use the hash pointed to by hashref, which is not a reference. The only way to use a hash operator in this context is to bind the dereference in a block, and then use the hash designator (%) like this:
%{$hashref->{OTHERS}}

which looks more complicated than it is. Just think of the curly brackets as parenthesis for syntax, and you will be fine.
This allows you to do something like:
foreach$i (keys %{$hashref->{OTHERS}}){
	print"$i, $hashref->{OTHERS}->{$i}\n";
}

It is often easier and clearer to use an intermediate variable to hold the hash reference like this:
$others = $hashref->{OTHERS};
foreach$i (keys %$others) {
	print"$i, $others->{$i}\n";
}


Anonymous Hashes

Anonymous hashes are similarly easy to create, except you use braces instead of square brackets:
$hash = { 'Man' => 'Bill',
'Woman' => 'Mary,
'Dog' => 'Ben'
};

The same arguments for the anonymous array composer also apply here. You can use any normal element such as
  1. a string literal (as in the preceding code),
  2. an expression, or
  3. a variable
to create the structure in question. Also note that the same principles for arrays of arrays can be applied to hashes, too, but we will cover the specifics of nested hash and array structures later in this module. Note that this composition procedure only works when Perl is expecting a term. That is, usually when making an assignment or expecting a hash or reference as an element. Braces are not only used for creating anonymous hashes, but they are also responsible for selecting hash subscript elements and for defining blocks within Perl. This means you must occasionally explicitly specify the creation of an anonymous hash reference by preceding the hash creator with a + or return:
$envref = +{ %ENV };
sub dupeenv{ return { %ENV } };

Hash Function - Exercise

Click the Exercise link below to answer several questions with respect to a hash example.
Hash Function - Exercise

SEMrush Software