Perl Cd Bookshelf [Electronic resources] نسخه متنی

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

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

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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



11.7. Using Closures Instead of Objects


11.7.1. Problem





You want records with private state,
behavior, and identity, but you don't want to learn object-oriented
programming to accomplish this.

11.7.2. Solution


Write a function that returns (by reference) a hash of code
references. These code references are closures created in the same
scope, so when they execute, they'll share bindings to the same
private variables.

11.7.3. Discussion


Because a closure is a binding of code and data, it can implement
what might be thought of as an object.

Here's an example that creates and returns a hash of anonymous
functions. mkcounter takes an argument of a seed
counter and returns a reference to a hash of code references that you
can use to manipulate the counter indirectly.

$c1 = mkcounter(20);
$c2 = mkcounter(77);
printf "next c1: %d\n", $c1->{NEXT}->( ); # 21
printf "next c2: %d\n", $c2->{NEXT}->( ); # 78
printf "next c1: %d\n", $c1->{NEXT}->( ); # 22
printf "last c1: %d\n", $c1->{PREV}->( ); # 21
printf "old c2: %d\n", $c2->{RESET}->( ); # 77

The code values in the hash references in $c1 and
$c2 maintain their own separate state. Here's how
to set that up:

sub mkcounter {
my $count = shift;
my $start = $count;
my $bundle = {
"NEXT" => sub { return ++$count },
"PREV" => sub { return --$count },
"GET" => sub { return $count },
"SET" => sub { $count = shift },
"BUMP" => sub { $count += shift },
"RESET" => sub { $count = $start },
};
$bundle->{"LAST"} = $bundle->{"PREV"};
return $bundle;
}

Because the lexical variables used by the closures in the
$bundle hash reference are returned by the
function, they are not deallocated. The next time
mkcounter is called, the closures get a different
set of variable bindings for the same code. Because no one outside
those closures can access these two variables, this assures true
privacy.

The assignment right before the return makes both
"PREV" and "LAST" values point
to the same closure. Depending on your object-oriented background,
you might think of these as being two different messages, both
implemented using the same method.

The bundle we return is not an object in that it has no obvious
inheritance and polymorphism. (Yet.) But it certainly does have
state, behavior, and identity, as well as encapsulation.

11.7.4. See Also


The section on "Closures" in Chapter 8 of Programming
Perl
and the discussion on closures in
perlref(1);
Recipe 11.4;
Recipe 11.9; Chapter 13



11.6. Creating Arrays of Scalar References11.8. Creating References to Methods




Copyright © 2003 O'Reilly & Associates. All rights reserved.

/ 875