Learning Perl Objects, References amp;amp; Modules [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Learning Perl Objects, References amp;amp; Modules [Electronic resources] - نسخه متنی

Randal L. Schwartz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید














3.6 Nested Data Structures


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.


Figure 3-1. The array @all_with_names holds a multilevel data structure containing strings and references to arrays


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.



/ 199