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

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

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

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

Randal L. Schwartz

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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














10.3 Indirect Object Notation


The arrow syntax used to invoke a method
is sometimes called the direct object syntax
because there's also the indirect
object syntax, also known as the "only
works sometimes" syntax, for reasons explained in a
moment. When you write:

Class->class_method(@args);
$instance->instance_method(@other);

you can generally replace it with:

classmethod Class @args;
instancemethod $instance @other;

A typical use of this is with the
new method, replacing:

my $obj = Some::Class->new(@constructor_params);

with:

my $obj = new Some::Class @constructor_params;

making the C++ people feel right at home. Of course, in Perl,
there's nothing special about the name
new, but at least the syntax is hauntingly
familiar.

Why the previous "generally"
caveat? Well, if the instance is something more complicated than a
simple scalar variable:

$somehash->{$somekey}->[42]->instance_method(@parms);

then you can't just swap it around like:

instance_method $somehash->{$somekey}->[42] @parms;

because the only things acceptable to indirect object syntax are a
bareword (e.g., a class name), a simple scalar variable, or braces
denoting a block returning either a blessed reference or a
classname.[6]

[6] Astute readers will note that these are
the same rules as for an indirect filehandle syntax, from which
indirect object syntax directly mirrors, as well as the rules for
specifying a reference to be dereferenced.


This
means you have to write it like so:

instance_method { $somehash->{$somekey}->[42] } @parms;

And that goes from simple to uglier in one step.
There's another downside: ambiguous parsing. When we
developed the classroom materials concerning indirect object
references, we wrote:

my $cow = Cow->named("Bessie");
print name $cow, " eats.\n";

because we were thinking about the indirect object equivalents for:

my $cow = Cow->named("Bessie");
print $cow->name, " eats.\n";

However, the latter works; the former
doesn't. We were getting no output. Finally, we
enabled warnings (via -w on the command
line)[7] and got this interesting series
of messages:

[7] Using -w should be the first
step when Perl does something you don't understand.
Or maybe it should be the zeroth because you should normally have
-w in effect whenever you're
developing code.


Unquoted string "name" may clash with future reserved word at ./foo line 92.
Name "main::name" used only once: possible typo at ./foo line 92.
print( ) on unopened filehandle name at ./foo line 92.

Ahh, so that line was being parsed as:

print name ($cow, " eats.\n");

In other words, print the list of items to the filehandle named
name. That's clearly not what we
wanted, so we had to add additional syntax to disambiguate the call.

This
leads us to our next strong suggestion:


Use direct object syntax at all times, except perhaps for the constructor call.

That exception acknowledges that most people write
new Class
... rather than
Class->new(...) and that most of us are fine
with that. However, there are circumstances in which even that can
lead to ambiguity (e.g., when a subroutine named
new has been seen, and the class name itself has
not been seen as a package). When in doubt, ignore indirect object
syntax. Your maintenance programmer will thank you.


/ 199