| home / programming / perl / learning / chap3 / 1 | [previous] [next] |
|
|
In this example, the array @_ contains
two elements, one of which is also an array. What if you take a reference to
an array that also contains a reference to an array? You end up with a complex
data structure, which can be quite useful.
For example, iterate over the data for the Skipper, Gilligan, and the Professor by first building a larger data structure holding the entire list of provision lists:
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);my @skipper_with_name = ("Skipper", \@skipper);my @professor = qw(sunscreen water_bottle slide_rule batteries radio);my @professor_with_name = ("Professor", \@professor);my @gilligan = qw(red_shirt hat lucky_socks water_bottle);my @gilligan_with_name = ("Gilligan", \@gilligan);
At this point, @skipper_with_name
has two elements, the second of which is an array reference, similar to what
was passed to the subroutine. Now group them all:
my @all_with_names = (\@skipper_with_name,\@professor_with_name,\@gilligan_with_name,);
Note that you have just three elements, each of which is a reference to an array, each of which has two elements: the name and its corresponding initial provisions. A picture of that is in Figure 3-1.
|
|
Therefore, $all_with_names[2] will
be the array reference for the Gilligan's data. If you dereference it as @{$all_with_names[2]},
you get a two-element array, "Gilligan"
and another array reference.
How would you access that array reference? Using your rules again,
it's ${$all_with_names[2]}[1]. In other words,
taking $all_with_names[2], you dereference it in
an expression that would be something like $DUMMY[1]
as an ordinary array, so you'll place {$all_with_names[2]}
in place of DUMMY.
How do you call the existing check_required_items(
) with this data structure? The following code is easy enough.
for my $person (@all_with_names) {my $who = $$person[0];my $provisions_reference = $$person[1];check_required_items($who, $provisions_reference);}
This requires no changes to the subroutine. $person
will be each of $all_with_names[0], $all_with_names[1],
and $all_with_names[2], as the loop progresses.
When you dereference $$person[0], you get "Skipper,"
"Professor," and "Gilligan," respectively. $$person[1]
is the corresponding array reference of provisions for that person.
Of course, you can shortcut this as well, since the entire dereferenced array matches the argument list precisely:
for my $person (@all_with_names) {check_required_items(@$person);}
or even:
check_required_items(@$_) for @all_with_names;
As you can see, various levels of optimization can lead to obfuscation. Be sure to consider where your head will be a month from now when you have to reread your own code. If that's not enough, consider the new person who takes over your job after you have left.
| home / programming / perl / learning / chap3 / 1 | [previous] [next] |
Created: March 27, 2003
Revised: July 15, 2003
URL: http://webreference.com/programming/perl/learning/chap3/1