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

📄 ch13_03.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
are binary.  Here's how we could overload <tt class="literal">&gt;&gt;</tt>to do something like <tt class="literal">chop</tt>:<blockquote><pre class="programlisting">package ShiftString;use overload    '&gt;&gt;' =&gt; \&amp;right_shift,    '""' =&gt; sub { ${ $_[0] } };sub new {    my $class = shift;    my $value = shift;    return bless \$value =&gt; $class;}sub right_shift {    my ($x, $y) = @_;    my $value = $$x;    substr($value, -$y) = "";    return bless \$value =&gt; ref($x);}$camel = ShiftString-&gt;new("Camel");$ram = $camel &gt;&gt; 2;print $ram;            # Cam</pre></blockquote></p></dd><dt><b><em class="emphasis">Assignment operators:</em> <tt class="literal">+=</tt><em class="emphasis">,</em> <tt class="literal">-=</tt><em class="emphasis">,</em> <tt class="literal">*=</tt><em class="emphasis">,</em> <tt class="literal">/=</tt><em class="emphasis">,</em> <tt class="literal">%=</tt><em class="emphasis">,</em> <tt class="literal">**=</tt><em class="emphasis">,</em> <tt class="literal">x=</tt><em class="emphasis">,</em> <tt class="literal">.=</tt><em class="emphasis">,</em> <tt class="literal">&lt;&lt;=</tt><em class="emphasis">,</em> <tt class="literal">&gt;&gt;=</tt><em class="emphasis">,</em> <tt class="literal">++</tt><em class="emphasis">,</em> <tt class="literal">--</tt></b></dt><dd><p><a name="INDEX-"></a><a name="INDEX-"></a>These assignment operators might change the value of their argumentsor leave them as is.  The result is assigned to the lefthand operandonly if the new value differs from the old one. This allows the samehandler to be used to overload both <tt class="literal">+=</tt> and<tt class="literal">+</tt>.  Although this is permitted, it is seldomrecommended, since by the semantics described later under "When anOverload Handler Is Missing (nomethod and fallback)", Perl will invokethe handler for <tt class="literal">+</tt> anyway, assuming<tt class="literal">+=</tt> hasn't been overloaded directly.</p><p><a name="INDEX-"></a>Concatenation (<tt class="literal">.=</tt>) can be autogenerated usingstringification followed by ordinary string concatenation. The<tt class="literal">++</tt> and <tt class="literal">--</tt> operators canbe autogenerated from <tt class="literal">+</tt> and <tt class="literal">-</tt>(or <tt class="literal">+=</tt> and <tt class="literal">-=</tt>).</p><p><a name="INDEX-"></a><a name="INDEX-"></a>Handlers implementing <tt class="literal">++</tt> and <tt class="literal">--</tt> are expected to <em class="emphasis">mutate</em> (alter)their arguments.  If you wanted autodecrement to work on letters aswell as numbers, you could do that with a handler as follows:<blockquote><pre class="programlisting">package MagicDec;use overload    q(--) =&gt; \&amp;decrement,    q("") =&gt; sub { ${ $_[0] } };sub new {    my $class = shift;    my $value = shift;    bless \$value =&gt; $class;}sub decrement {    my @string = reverse split(//, ${ $_[0] } );    my $i;    for ($i = 0; $i &lt; @string; $i++ ) {        last unless $string[$i] =~ /a/i;        $string[$i] = chr( ord($string[$i]) + 25 );    }    $string[$i] = chr( ord($string[$i]) - 1 );    my $result = join('', reverse @string);    $_[0] = bless \$result =&gt; ref($_[0]);}package main;for $normal (qw/perl NZ Pa/) {    $magic = MagicDec-&gt;new($normal);    $magic--;    print "$normal goes to $magic\n";}</pre></blockquote>That prints out:<blockquote><pre class="programlisting">perl goes to perkNZ goes to NYPa goes to Oz</pre></blockquote>exactly reversing Perl's magical string autoincrement operator.<a name="INDEX-"></a></p><p>The <tt class="literal">++$a</tt> operation can be autogenerated using<tt class="literal">$a += 1</tt> or <tt class="literal">$a = $a + 1</tt>, and<tt class="literal">$a--</tt> using <tt class="literal">$a -= 1</tt> or<tt class="literal">$a = $a - 1</tt>.  However, this does not trigger thecopying behavior that a real <tt class="literal">++</tt> operator would.See "The Copy Constructor" later in this chapter.</p></dd><dt><b><em class="emphasis">Comparison operators:</em><tt class="literal">==</tt><em class="emphasis">,</em><tt class="literal">&lt;</tt><em class="emphasis">,</em><tt class="literal">&lt;=</tt><em class="emphasis">,</em><tt class="literal">&gt;</tt><em class="emphasis">,</em><tt class="literal">&gt;=</tt><em class="emphasis">,</em><tt class="literal">!=</tt><em class="emphasis">,</em><tt class="literal">&lt;=&gt;</tt><em class="emphasis">,</em><tt class="literal">lt</tt><em class="emphasis">,</em><tt class="literal">le</tt><em class="emphasis">,</em><tt class="literal">gt</tt><em class="emphasis">,</em><tt class="literal">ge</tt><em class="emphasis">,</em><tt class="literal">eq</tt><em class="emphasis">,</em><tt class="literal">ne</tt><em class="emphasis">,</em> <tt class="literal">cmp</tt></b></dt><dd><p><a name="INDEX-"></a><a name="INDEX-"></a>If <tt class="literal">&lt;=&gt;</tt> is overloaded, it can be used toautogenerate behaviors for <tt class="literal">&lt;</tt>,<tt class="literal">&lt;=</tt>, <tt class="literal">&gt;</tt>,<tt class="literal">&gt;=</tt>, <tt class="literal">==</tt>, and<tt class="literal">!=</tt>.  Similarly, if <tt class="literal">cmp</tt> isoverloaded, it can be used to autogenerate behaviors for<tt class="literal">lt</tt>, <tt class="literal">le</tt>, <tt class="literal">gt</tt>,<tt class="literal">ge</tt>, <tt class="literal">eq</tt>, and<tt class="literal">ne</tt>.</p><p><a name="INDEX-"></a><a name="INDEX-"></a>Note that overloading <tt class="literal">cmp</tt> won't let you sortobjects as easily as you'd like, because what will be compared arethe stringified versions of the objects instead of the objectsthemselves.  If that was yourgoal, you'd want to overload <tt class="literal">""</tt> as well.</p></dd><dt><b><em class="emphasis">Mathematical functions:</em> <tt class="literal">atan2</tt><em class="emphasis">,</em> <tt class="literal">cos</tt><em class="emphasis">,</em> <tt class="literal">sin</tt><em class="emphasis">,</em> <tt class="literal">exp</tt><em class="emphasis">,</em> <tt class="literal">abs</tt><em class="emphasis">,</em> <tt class="literal">log</tt><em class="emphasis">,</em> <tt class="literal">sqrt</tt></b></dt><dd><p><a name="INDEX-"></a><a name="INDEX-"></a>If <tt class="literal">abs</tt> is unavailable, it can be autogenerated from<tt class="literal">&lt;</tt> or <tt class="literal">&lt;=&gt;</tt> combined witheither unary minus or subtraction.</p><p>An overloaded <tt class="literal">-</tt> can be used to autogenerate missinghandlers for unary minus or for the <tt class="literal">abs</tt> function,which may also be separately overloaded.  (Yes, we know that<tt class="literal">abs</tt> looks like a function, whereas unary minuslooks like an operator, but they aren't all that different as far asPerl's concerned.)</p></dd><dt><b><em class="emphasis">Iterative operator:</em> <tt class="literal">&lt;&gt;</tt></b></dt><dd><a name="INDEX-"></a><a name="INDEX-"></a><p>The <tt class="literal">&lt;&gt;</tt> handler can be triggered by usingeither <tt class="literal">readline</tt> (when it reads from a filehandle,as in <tt class="literal">while (&lt;FH&gt;)</tt>) or<tt class="literal">glob</tt> (when it is used for fileglobbing, as in<tt class="literal">@files = &lt;*.*&gt;</tt>).<blockquote><pre class="programlisting">package LuckyDraw; use overload    '&lt;&gt;' =&gt; sub {        my $self = shift;        return splice @$self, rand @$self, 1;    };  sub new {    my $class = shift;    return bless [@_] =&gt; $class;} package main; $lotto = new LuckyDraw 1 .. 51; for (qw(1st 2nd 3rd 4th 5th 6th)) {    $lucky_number = &lt;$lotto&gt;;    print "The $_ lucky number is: $lucky_number.\n";} $lucky_number = &lt;$lotto&gt;;print "\nAnd the bonus number is: $lucky_number.\n";</pre></blockquote>In California, this prints:<blockquote><pre class="programlisting">The 1st lucky number is: 18The 2nd lucky number is: 11The 3rd lucky number is: 40The 4th lucky number is: 7The 5th lucky number is: 51The 6th lucky number is: 33 And the bonus number is: 5</pre></blockquote></p></dd><dt><b><em class="emphasis">Dereference operators:</em> <tt class="literal">${}</tt><em class="emphasis">,</em> <tt class="literal">@{}</tt><em class="emphasis">,</em> <tt class="literal">%{}</tt><em class="emphasis">,</em> <tt class="literal">&amp;{}</tt><em class="emphasis">,</em> <tt class="literal">*{}</tt></b></dt><dd><p><a name="INDEX-"></a><a name="INDEX-"></a>Attempts to dereference scalar, array, hash, subroutine, and globreferences can be intercepted by overloading these five symbols.</p><p><a name="INDEX-"></a>The online Perl documentation for <tt class="literal">overload</tt> demonstrates how you canuse this operator to simulate your own pseudohashes.  Here's a simpler examplethat implements an object as an anonymous array but permits hashreferencing.  Don't try to treat it as a real hash; you won't be ableto <tt class="literal">delete</tt> key/value pairs from the object.  If you want to combinearray and hash notations, use a real pseudohash (as it were).<blockquote><pre class="programlisting">package PsychoHash;use overload '%{}' =&gt; \&amp;as_hash;sub as_hash {    my ($x) = shift;    return { @$x };}sub new {    my $class = shift;    return bless [ @_ ] =&gt; $class;}$critter = new PsychoHash( height =&gt; 72, weight =&gt; 365, type =&gt; "camel" );print $critter-&gt;{weight};   # prints 365</pre></blockquote>Also see <a href="ch14_01.htm">Chapter 14, "Tied Variables"</a>, for a mechanism to let you redefine basicoperations on hashes, arrays, and scalars.</p></dd></dl><p></p><p><a name="INDEX-2622"></a><a name="INDEX-2623"></a><a name="INDEX-2624"></a><a name="INDEX-2625"></a>When overloading an operator, try not to create objects with referencesto themselves.  For instance,<blockquote><pre class="programlisting">use overload '+' =&gt; sub { bless [ \$_[0], \$_[1] ] };</pre></blockquote>This is asking for trouble, since if you say <tt class="literal">$animal +=$vegetable</tt>, the result will make <tt class="literal">$animal</tt>a reference to a blessed array reference whose first element is<tt class="literal">$animal</tt>.  This is a <em class="emphasis">circularreference</em>, which means that even if you destroy<tt class="literal">$animal</tt>, its memory won't be freed until yourprocess (or interpreter) terminates.  See "Garbage Collection,Circular References, and Weak References" in <a href="ch08_01.htm">Chapter 8, "References"</a>.</p><a name="INDEX-2626"></a><a name="INDEX-2627"></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="ch13_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="ch13_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">13.2. Overload Handlers</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">13.4. The Copy Constructor (=)</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 + -