⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch12_03.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
call:<blockquote><pre class="programlisting">$mage = summon Wizard "Gandalf";$nemesis = summon Balrog home =&gt; "Moria", weapon =&gt; "whip";move $nemesis "bridge";speak $mage "You cannot pass";break $staff;               # safer to use: break $staff ();</pre></blockquote>The list operator syntax should be familiar to you; it's the same styleused for passing filehandles to <tt class="literal">print</tt> or <tt class="literal">printf</tt>:<blockquote><pre class="programlisting">print STDERR "help!!!\n";</pre></blockquote>It's also similar to English sentences like "Give Gollum thePreciousss", so we call it the <em class="emphasis">indirect object</em> form.  The invocantis expected in the <em class="emphasis">indirect object slot</em>.  When you read aboutpassing a built-in function like <tt class="literal">system</tt> or <tt class="literal">exec</tt> something in its"indirect object slot", this means that you're supplying this extra,comma-less argument in the same place you would when you invoke a methodusing the indirect object syntax.</p><p>The indirect object form even permits you to specify the <em class="replaceable">INVOCANT</em>as a <em class="replaceable">BLOCK</em> that evaluates to an object (reference) or class(package).  This lets you combine those two invocations into onestatement this way:<blockquote><pre class="programlisting">speak { summon Wizard "Gandalf" } "friend";</pre></blockquote></p><h3 class="sect2">12.3.3. Syntactic Snafus with Indirect Objects</h3><p><a name="INDEX-2384"></a>One syntax will often be more readable than the other.  The indirectobject syntax is less cluttered, but suffers from several forms ofsyntactic ambiguity.  The first is that the <em class="replaceable">LIST</em> part of anindirect object invocation is parsed the same as any other listoperator.  Thus, the parentheses of:<blockquote><pre class="programlisting">enchant $sword ($pips + 2) * $cost;</pre></blockquote>are assumed to surround all the arguments, regardless of what comesafterward.  It would therefore be be equivalent to this:<blockquote><pre class="programlisting">($sword-&gt;enchant($pips + 2)) * $cost;</pre></blockquote><a name="INDEX-2385"></a><a name="INDEX-2386"></a><a name="INDEX-2387"></a><a name="INDEX-2388"></a><a name="INDEX-2389"></a><a name="INDEX-2390"></a><a name="INDEX-2391"></a>That's unlikely to do what you want: <tt class="literal">enchant</tt> is only beingcalled with <tt class="literal">$pips + 2</tt>, and the method's return value is thenmultiplied by <tt class="literal">$cost</tt>.  As with other list operators,you must also be careful of the precedence of <tt class="literal">&amp;&amp;</tt> and <tt class="literal">||</tt>versus <tt class="literal">and</tt> and <tt class="literal">or</tt>.</p><p>For example, this:<blockquote><pre class="programlisting">name $sword $oldname || "Glamdring";   # can't use "or" here!</pre></blockquote>becomes the intended:<blockquote><pre class="programlisting">$sword-&gt;name($oldname || "Glamdring");</pre></blockquote>but this:<blockquote><pre class="programlisting">speak $mage "friend" &amp;&amp; enter();        # should've been "and" here!</pre></blockquote>becomes the dubious:<blockquote><pre class="programlisting">$mage-&gt;speak("friend" &amp;&amp; enter());</pre></blockquote>which could be fixed by rewriting into one of these equivalent forms:<blockquote><pre class="programlisting">enter() if $mage-&gt;speak("friend");$mage-&gt;speak("friend") &amp;&amp; enter();speak $mage "friend" and enter();</pre></blockquote>The second syntactic infelicity of the indirect object form is thatits <em class="replaceable">INVOCANT</em> is limited to a name, an unsubscripted scalarvariable, or a block.<a href="#FOOTNOTE-4">[4]</a> As soon as theparser sees one of these, it has its <em class="replaceable">INVOCANT</em>, so it starts lookingfor its <em class="replaceable">LIST</em>.  So these invocations:<blockquote><pre class="programlisting">move $party-&gt;{LEADER};               # probably wrong!move $riders[$i];                    # probably wrong!</pre></blockquote>actually parse as these:<blockquote><pre class="programlisting">$party-&gt;move-&gt;{LEADER};$riders-&gt;move([$i]);</pre></blockquote>rather than what you probably wanted:<blockquote><pre class="programlisting">$party-&gt;{LEADER}-&gt;move;$riders[$i]-&gt;move;</pre></blockquote>The parser only looks a little ways ahead to find the invocant for anindirect object, not even as far as it would look for a unaryoperator.  This oddity does not arise with the firstnotation, so you might wish to stick with the arrow as your weapon ofchoice.</p><blockquote class="footnote"><a name="FOOTNOTE-4"></a><p>[4] Attentive readers will recall that thisis precisely the same list of syntactic items that are allowed after afunny character to indicate a variable dereference--for example,<tt class="literal">@ary</tt>, <tt class="literal">@$aryref</tt>, or <tt class="literal">@{$aryref}</tt>.</p></blockquote><p>Even English has a similar issue here.  Think about the command, "Throwyour cat out the window a toy mouse to play with."  If you parse thatsentence too quickly, you'll end up throwing the cat, not the mouse(unless you notice that the cat is already out the window).  Like Perl,English has two different syntaxes for expressing the agent: "Throwyour cat the mouse" and "Throw the mouse to your cat."  Sometimes thelonger form is clearer and more natural, and sometimes the shorter oneis.  At least in Perl, you're required to use braces around any complicatedindirect object.</p><h3 class="sect2">12.3.4. Package-Quoted Classes</h3><a name="INDEX-2392"></a><a name="INDEX-2393"></a><a name="INDEX-2394"></a><a name="INDEX-2395"></a><p>The final syntactic ambiguity with the indirect object style ofmethod invocation is that it may not be parsed as a method call atall, because the current package may have a subroutine of the samename as the method.  When using a class method with a literal packagename as the invocant, there is a way to resolve this ambiguitywhile still keeping the indirect object syntax: package-quote theclassname by appending a double colon to it.<blockquote><pre class="programlisting">$obj = method <em class="replaceable">CLASS</em>::;   # forced to be "<em class="replaceable">CLASS</em>"-&gt;method</pre></blockquote>This is important because the commonly seen notation:<blockquote><pre class="programlisting">$obj = new <em class="replaceable">CLASS</em>;        # might not parse as method</pre></blockquote>will not always behave properly if the current package has asubroutine named <tt class="literal">new</tt> or <em class="replaceable">CLASS</em>.  Even if you studiously usethe arrow form instead of the indirect object form to invoke methods,this can, on rare occasion, still be a problem.  At the cost ofextra punctuation noise, the <em class="replaceable">CLASS</em><tt class="literal">::</tt> notation guarantees howPerl will parse your method invocation.  The first two examples below donot always parse the same way, but the second two do:<blockquote><pre class="programlisting">$obj = new ElvenRing;               # could be new("ElvenRing")                                    # or even new(ElvenRing())$obj = ElvenRing-&gt;new;              # could be ElvenRing()-&gt;new()$obj = new ElvenRing::;             # always "ElvenRing"-&gt;new()$obj = ElvenRing::-&gt;new;            # always "ElvenRing"-&gt;new()</pre></blockquote>This package-quoting notation can be made prettier with some creativealignment:<blockquote><pre class="programlisting">$obj = new ElvenRing::            name    =&gt; "Narya",            owner   =&gt; "Gandalf",            domain  =&gt; "fire",            stone   =&gt; "ruby";</pre></blockquote><a name="INDEX-2396"></a>Still, you may say, "Oh, ugh!" at that double colon, so we'll tell youthat you can almost always get away with a bare class name, providedtwo things are true.  First, there is no subroutine of the samename as the class.  (If you follow the convention that subroutine names like<tt class="literal">new</tt> start lowercase and class names like <tt class="literal">ElvenRing</tt> startuppercase, this is never a problem.)  Second, the class hasbeen loaded with one of:<blockquote><pre class="programlisting">use ElvenRing;require ElvenRing;</pre></blockquote>Either of these declarations ensures that Perl knows <tt class="literal">ElvenRing</tt> is amodule name, which forces any bare name like <tt class="literal">new</tt> before the classname <tt class="literal">ElvenRing</tt> to be interpreted as a method call, even if youhappen to have declared a <tt class="literal">new</tt> subroutine of your own in the currentpackage.  People don't generally get into trouble with indirect objectsunless they start cramming multiple classes into the same file, inwhich case Perl might not know that a particular package name wassupposed to be a class name.  People who name subroutines with namesthat look like <tt class="literal">ModuleNames</tt> also come to grief eventually.<a name="INDEX-2397"></a><a name="INDEX-2398"></a></p><a name="INDEX-2399"></a><a name="INDEX-2400"></a><!-- BOTTOM NAV BAR --><hr width="515" align="left"><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="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></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><tr><td align="left" valign="top" width="172">12.2. Perl's Object System</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">12.4. Object Construction</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -