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

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

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

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

Randal L. Schwartz

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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














3.1 Performing the Same Task on Many Arrays


Before the Minnow can leave on an excursion (e.g., a three-hour
tour), every passenger and crew member should be checked to ensure
they have all the required trip items in their possession.
Let's say that for maritime safety, every person on
board the Minnow needs to have a life preserver, some sunscreen, a
water bottle, and a rain jacket. You can write a bit of code to check
for the Skipper's supplies:

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

The grep in a scalar
context returns the number of times the expression
$item eq $_
returns true, which is 1 if the item is in the list and 0 if
not.[1] If the value is 0, it's false, and you
print the message.

[1] There are more efficient ways to check list
membership for large lists, but for a few items, this is probably the
easiest way to do so with just a few lines of code.


Of course, if you want to check on Gilligan and the Professor, you
might write the following code:

my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
for my $item (@required) {
unless (grep $item eq $_, @gilligan) { # not found in list?
print "gilligan is missing $item.\n";
}
}
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
for my $item (@required) {
unless (grep $item eq $_, @professor) { # not found in list?
print "professor is missing $item.\n";
}
}

You may start to notice a lot of repeated code here and decide that
it would be served best in a subroutine:

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

The subroutine is given five items in
its @_ array initially: the name
gilligan and the four items belonging to Gilligan.
After the shift, @_ will have
only the items. Thus, the grep checks each
required item against the list.

So far, so good. You can check the Skipper and the Professor with
just a bit more code:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
check_required_items("skipper", @skipper);
check_required_items("professor", @professor);

And for the other passengers, you repeat as needed. Although this
code meets the initial requirements, you've got two
problems to deal with:


To create
@_, Perl copies the entire contents of the array
to be scanned. This is fine for a few items, but if the array is
large, it seems a bit wasteful to copy the data just to pass it into
a subroutine.


Suppose you want to modify the original array to force the provisions
list to include the mandatory items. Because you have a copy in the
subroutine ("pass by value"), any
changes made to @_ aren't
reflected automatically in the corresponding provisions
array.[2]

[2] Actually, assigning new scalars to elements of
@_ after the shift modifies the
corresponding variable being passed, but that still
wouldn't let you extend the array with additional
mandatory provisions.



To solve either or both of these problems, you need pass by reference
rather than pass by value. And that's just what the
doctor (or Professor) ordered.



/ 199