Perl Basics   «Prev  Next»

Lesson 21More-complex data structures
ObjectiveLearn how to work with arbitrary aggregations of aggregations.

Perl Complex Data Structures

Now that we have seen that you can create anonymous hashes and arrays and that they can be included in themselves, why not in each other?
For example, it is possible to use anonymous hashes within an array. Consider this structure for our presidential data:

@administration = (
 {
  PREZ => 'Richard M. Nixon',
  VEEP => [ 'Spiro T. Agnew', 'NONE', 'Gerald R. Ford' ],
  YEAR => 1969,
 }, 
 {
  PREZ => 'Gerald R. Ford',
  VEEP => [ 'NONE', 'Nelson A. Rockefeller' ],
  YEAR => 1974,
 }, 
 {
  PREZ => 'Jimmy Carter',
  VEEP => [ 'Walter F. Mondale' ],
  YEAR => 1977,
 }, 
 {
  PREZ => 'Ronald W. Reagan',
  VEEP => [ 'George H. Bush' ],
  YEAR => 1981,
 }, 
 {
  PREZ => 'George Bush',
  VEEP => [ 'J. Dan Quayle' ],
  YEAR => 1989,
 }, 
 {
  PREZ => 'Bill Clinton',
  VEEP => [ 'Al Gore, Jr.' ],
  YEAR => 1993,
 }
);


1) President, 2) Vice President and 3) Year

Here's a graphical representation of this data structure:
Data structure consisting of 1) President, 2) Vice President, 3) Year
Data structure consisting of 1) President, 2) Vice President, 3) Year

Notice that some of our presidents had more than one vice president.
That's an array in a hash in an array. How do you access data like this?
The following is a loop that prints the above data.

foreach$rec (@administration) {
  print"$rec->{PREZ}:\n"; 
  $veep = join(", ", @{$rec->{VEEP}});
  print" VP: $veep\n";
  print" took office in $rec->{YEAR}\n\n";
}

Here's a quick analysis of how this works:
The foreach loop steps through the outer array. For each element, the variable $rec will be a reference to the anonymous hash for that president. That is because each element of the @administration array is an anonymous hash with the data for one president.

Within the loop

Wihin the loop we first print the name of the president with $rec->{PREZ}.
Then we want to print any and all VPs that president may have committed crimes served with.
We do this with join, so that we can easily print commas between them. But this dereference may be new:
@{$rec->{VEEP}}
We have to do it this way because $rec->{VEEP} does not do what you may expect it to do. Remember, those funny characters at the beginning of the dereference are not operators, and they do not bind like you would expect operators to (especially if you have any experience with C).
Using the curly brackets creates what is effectively an anonymous function that returns the value of $rec->{VEEP}, which, conveniently enough, is the reference to the array with all the vice presidents in it. Then the ${ ... } expression can properly dereference it, pass it to join and voilà, we have vice presidents!
The easy way to think of the braces is like parenthesis for dereferences. That will help you keep them straight.

Perl Data Structure - Exercise

Click the Exercise link below to rework the program you wrote for the "Perl hashes" exercise.
Perl Data Structure - Exercise