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

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

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

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

Randal L. Schwartz

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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














3.3 Dereferencing the Array Reference



If you look at
@skipper, you'll see that it
consists of two parts: the @ symbol and the name
of the array. Similarly, the syntax $skipper[1]
consists of the name of the array in the middle and some syntax
around the outside to get at the second element of the array (index
value 1 is the second element because you start counting index values
at 0).

Here's
the trick: any reference to an array can be placed in curly braces
and written in place of the name of an array, ending up with a method
to access the original array. That is, wherever you write
skipper to name the array, you use the reference
inside curly braces: { $items }. For example, both
of these lines refer to the entire array:

@  skipper
@{ $items }

whereas both of these refer to the second item of the
array:[3]

[3] Note that whitespace was added in these two
displays to make the similar parts line up. This whitespace is legal
in a program, even though most programs won't use
it.


$  skipper [1]
${ $items }[1]

By using the reference form, you've decoupled the
code and the method of array access from the actual array.
Let's see how that changes the rest of this
subroutine:

sub check_required_items {
my $who = shift;
my $items = shift;
my @required = qw(preserver sunscreen water_bottle jacket);
for my $item (@required) {
unless (grep $item eq $_, @{$items}) { # not found in list?
print "$who is missing $item.\n";
}
}
}

All you did was replace
@_ (the copy of the provisions list) with
@{$items}, a dereferencing of the reference to the
original provisions array. Now you can call the subroutine a few
times as before:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
check_required_items("The Skipper", \@skipper);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
check_required_items("Professor", \@professor);
my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
check_required_items("Gilligan", \@gilligan);

In
each case, $items points to a different array, so
the same code applies to different arrays each time it is invoked.
This is one of the most important uses of references: decoupling the
code from the data structure on which it operates so the code can be
reused more readily.

Passing
the array by reference fixes the first of the two problems mentioned
earlier. Now, instead of copying the entire provision list into the
@_ array, you get a single element of a reference
to that provisions array.

Could you have eliminated the two
shifts at the beginning of the subroutine? Sure,
at the expense of clarity:

sub check_required_items {
my @required = qw(preserver sunscreen water_bottle jacket);
for my $item (@required) {
unless (grep $item eq $_, @{$_[1]}) { # not found in list?
print "$_[0] is missing $item.\n";
}
}
}


You still have two elements in
@_. The first element is the passenger or crew
member name and is used in the error message. The second element is a
reference to the correct provisions array, used in the
grep expression.



/ 199