📄 ch12_03.htm
字号:
<html><head><title>Method Invocation (Programming Perl)</title><!-- STYLESHEET --><link rel="stylesheet" type="text/css" href="../style/style1.css"><!-- METADATA --><!--Dublin Core Metadata--><meta name="DC.Creator" content=""><meta name="DC.Date" content=""><meta name="DC.Format" content="text/xml" scheme="MIME"><meta name="DC.Generator" content="XSLT stylesheet, xt by James Clark"><meta name="DC.Identifier" content=""><meta name="DC.Language" content="en-US"><meta name="DC.Publisher" content="O'Reilly & Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Method Invocation"><meta name="DC.Type" content="Text.Monograph"></head><body><!-- START OF BODY --><!-- TOP BANNER --><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home"><map name="banner-map"><AREA SHAPE="RECT" COORDS="0,0,466,71" HREF="index.htm" ALT="Programming Perl"><AREA SHAPE="RECT" COORDS="467,0,514,18" HREF="jobjects/fsearch.htm" ALT="Search this book"></map><!-- TOP NAV BAR --><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch12_02.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch12_01.htm">Chapter 12: Objects</a></td><td align="right" valign="top" width="172"><a href="ch12_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h2 class="sect1">12.3. Method Invocation</h2><a name="INDEX-2362"></a><a name="INDEX-2363"></a><p><a name="INDEX-2364"></a><a name="INDEX-2365"></a><a name="INDEX-2366"></a>If you were to boil down all of object-oriented programming into onequintessential notion, it would be <em class="emphasis">abstraction</em>. It's the singleunderlying theme you'll find running through all those 10-dollar wordsthat OO enthusiasts like to bandy about, like polymorphism andinheritance and encapsulation. We believe in those fancy words, butwe'll address them from the practical viewpoint of what it means toinvoke methods. Methods lie at the heart of the object system becausethey provide the abstraction layer needed to implement all these fancyterms. Instead of directly accessing a piece of data sitting in anobject, you invoke an instance method. Instead of directly calling asubroutine in some package, you invoke a class method. By interposingthis level of indirection between class use and class implementation,the program designer remains free to tinker with the internal workings of theclass, with little risk of breaking programs that use it.</p><p><a name="INDEX-2367"></a><a name="INDEX-2368"></a><a name="INDEX-2369"></a><a name="INDEX-2370"></a>Perl supports two different syntactic forms for invoking methods. Oneuses a familiar style you've already seen elsewhere in Perl, and thesecond is a form you may recognize from other programming languages.No matter which form of method invocation is used, the subroutineconstituting the method is always passed an extra initial argument.If a class is used to invoke the method, that argument will be thename of the class. If an object is used to invoke the method, thatargument will be the reference to the object. Whichever it is, we'llcall it the method's <em class="emphasis">invocant</em>. For a class method, the invocant isthe name of a package. For an instance method, the invocant is areference that specifies an object.</p><p>In other words, the invocant is whatever the method was invoked<em class="emphasis">with</em>. Some OO literature calls this the method's <em class="emphasis">agent</em> or its<em class="emphasis">actor</em>. Grammatically, the invocant is neither the subject of theaction nor the receiver of that action. It's more like an indirectobject, the beneficiary on whose behalf the action is performed--justlike the word "me" in the command, "Forge me a sword!" Semantically,you can think of the invocant as either an invoker or an invokee,whichever fits better into your mental apparatus. We're not goingto tell you how to think. (Well, not about that.)</p><p><a name="INDEX-2371"></a><a name="INDEX-2372"></a><a name="INDEX-2373"></a>Most methods are invoked explicitly, but methods may also be invokedimplicitly when triggered by object destructors, overloaded operators,or tied variables. Properly speaking, these are not regularsubroutine calls, but rather method invocations automatically triggeredby Perl on behalf of an object. Destructors are described later inthis chapter, overloading is described in<a href="ch13_01.htm">Chapter 13, "Overloading"</a>,and ties are described in <a href="ch14_01.htm">Chapter 14, "Tied Variables"</a>.</p><p><a name="INDEX-2374"></a><a name="INDEX-2375"></a><a name="INDEX-2376"></a><a name="INDEX-2377"></a>One difference between methods and regular subroutines is when theirpackages are resolved--that is, how early (or late) Perl decides whichcode should be executed for the method or subroutine. A subroutine'spackage is resolved during compilation, before your program begins torun.<a href="#FOOTNOTE-3">[3]</a> In contrast, a method's packageisn't resolved until it is actually invoked. (Prototypes are checkedat compile time, which is why regular subroutines can use them butmethods can't.)</p><blockquote class="footnote"><a name="FOOTNOTE-3"></a><p>[3] More precisely, the subroutine call is resolveddown to a particular typeglob, a reference to which is stuffed intothe compiled opcode tree. The meaning of that typeglob is negotiableeven at run time--this is how <tt class="literal">AUTOLOAD</tt> can autoloada subroutine for you. Normally, however, the meaning of the typeglobis also resolved at compile time by the definition of an appropriatelynamed subroutine.</p></blockquote><p>The reason a method's package can't be resolved earlier is relativelystraightforward: the package is determined by the class of theinvocant, and the invocant isn't known until the method is actuallyinvoked. At the heart of OO is this simple chain of logic: oncethe invocant is known, the invocant's class is known, and once theclass is known, the class's inheritance is known, and once the class'sinheritance is known, the actual subroutine to call is known.</p><p>The logic of abstraction comes at a price. Because of the lateresolution of methods, an object-oriented solution in Perl is likely torun slower than the corresponding non-OO solution. For some of thefancier techniques described later, it could be a <em class="emphasis">lot</em> slower. However, manycommon problems are solved not by working faster, but by workingsmarter. That's where OO shines.</p><h3 class="sect2">12.3.1. Method Invocation Using the Arrow Operator</h3><p><a name="INDEX-2378"></a><a name="INDEX-2379"></a><a name="INDEX-2380"></a>We mentioned that there are two styles of method invocation. Thefirst style for invoking a method looks like this:<blockquote><pre class="programlisting"><em class="replaceable">INVOCANT</em>-><em class="replaceable">METHOD</em>(<em class="replaceable">LIST</em>)<em class="replaceable">INVOCANT</em>-><em class="replaceable">METHOD</em></pre></blockquote></p><p>For obvious reasons, this style is usually called the arrow form ofinvocation. (Do not confuse <tt class="literal">-></tt> with <tt class="literal">=></tt>, the"double-barreled" arrow used as a fancy comma.) Parentheses arerequired if there are any arguments. When executed, the invocationfirst locates the subroutine determined jointly by the class of the<em class="replaceable">INVOCANT</em> and the <em class="replaceable">METHOD</em> name, and then calls that subroutine, passing<em class="replaceable">INVOCANT</em> as its first argument.</p><p>When <em class="replaceable">INVOCANT</em> is a reference, we say that<em class="replaceable">METHOD</em> is invoked as an instance method,and when <em class="replaceable">INVOCANT</em> is a package name, we saythat <em class="replaceable">METHOD</em> is invoked as a class method.There really is no difference between the two, other than that thepackage name is more obviously associated with the class itself thanwith the objects of the class. You'll have to take our word for itthat the objects also know their class. We'll tell you in a bit howto associate an object with a class name, but you can use objectswithout knowing that.</p><p>For example, to construct an object using the class method <tt class="literal">summon</tt>and then invoke the instance method <tt class="literal">speak</tt> on the resulting object,you might say this:<blockquote><pre class="programlisting">$mage = Wizard->summon("Gandalf"); # class method$mage->speak("friend"); # instance method</pre></blockquote>The <tt class="literal">summon</tt> and <tt class="literal">speak</tt> methods are defined by the <tt class="literal">Wizard</tt>class--or one of the classes from which it inherits. But you shouldn'tworry about that. Do not meddle in the affairs of Wizards.</p><p>Since the arrow operator is left associative (see <a href="ch03_01.htm">Chapter 3, "Unary and Binary Operators"</a>), you can even combine the two statements into one:<blockquote><pre class="programlisting">Wizard->summon("Gandalf")->speak("friend");</pre></blockquote>Sometimes you want to invoke a method without knowing its name aheadof time. You can use the arrow form of method invocation and replacethe method name with a simple scalar variable:<blockquote><pre class="programlisting">$method = "summon";$mage = Wizard->$method("Gandalf"); # Invoke Wizard->summon$travel = $companion eq "Shadowfax" ? "ride" : "walk";$mage->$travel("seven leagues"); # Invoke $mage->ride or $mage->walk</pre></blockquote>Although you're using the name of the method to invoke it indirectly,this usage is not forbidden by <tt class="literal">use strict 'refs'</tt>, since <em class="emphasis">all</em> methodcalls are in fact looked up symbolically at the time they're resolved.</p><p>In our example, we stored the name of a subroutine in <tt class="literal">$travel</tt>, butyou could also store a subroutine reference. This bypasses the methodlookup algorithm, but sometimes that's exactly what you want to do. See boththe section <a href="ch12_05.htm#ch12-sect-pm">Section 12.5.5, "Private Methods"</a> and the discussion of the <tt class="literal">can</tt>method in the section <a href="ch12_05.htm#ch12-sect-uni">Section 12.5.3, "UNIVERSAL: The Ultimate Ancestor Class"</a>. Tocreate a reference to a particular method being called on a particularinstance, see the section <a href="ch08_03.htm#ch08-sect-closure">Section 12.3.7, "Closures"</a> in <a href="ch08_01.htm">Chapter 8, "References"</a>.</p><h3 class="sect2">12.3.2. Method Invocation Using Indirect Objects</h3><p><a name="INDEX-2381"></a><a name="INDEX-2382"></a><a name="INDEX-2383"></a>The second style of method invocation looks like this:<blockquote><pre class="programlisting"><em class="replaceable">METHOD</em> <em class="replaceable">INVOCANT</em> (<em class="replaceable">LIST</em>)<em class="replaceable">METHOD</em> <em class="replaceable">INVOCANT</em> <em class="replaceable">LIST</em><em class="replaceable">METHOD</em> <em class="replaceable">INVOCANT</em></pre></blockquote></p><p>The parentheses around <em class="replaceable">LIST</em> are optional;if omitted, the method acts as a list operator. So you can havestatements like the following, all of which use this style of method
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -