ch13_15.htm

来自「By Tom Christiansen and Nathan Torkingto」· HTM 代码 · 共 793 行 · 第 1/2 页

HTM
793
字号
} # this uses stringifysub concat {     my ($s1, $s2, $inverted) = @_;    return StrNum $inverted ? ($s2 . $s1) : ($s1 . $s2);} # this uses stringifysub repeat {     my ($s1, $s2, $inverted) = @_;    return StrNum $inverted ? ($s2 x $s1) : ($s1 x $s2);}1;<ACLASS="indexterm"NAME="ch13-idx-1000005577-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000005577-1"></A></PRE></DIV></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-16506">Example: Overloaded FixNum Class</A></H3><PCLASS="para"><ACLASS="indexterm"NAME="ch13-idx-1000006591-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000006591-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000006591-2"></A><ACLASS="indexterm"NAME="ch13-idx-1000006591-3"></A><ACLASS="indexterm"NAME="ch13-idx-1000006591-4"></A>This class uses operator overloading to control the number of decimal places in output. It still uses full precision for its operations. A <CODECLASS="literal">places()</CODE> method can be used on the class or a particular object to set the number of places of output to the right of the decimal point.</P><PRECLASS="programlisting">#!/usr/bin/perl# demo_fixnum - show operator overloadinguse FixNum;FixNum-&gt;places(5);$x = FixNum-&gt;new(40);$y = FixNum-&gt;new(12);print &quot;sum of $x and $y is &quot;, $x + $y, &quot;\n&quot;;print &quot;product of $x and $y is &quot;, $x * $y, &quot;\n&quot;;$z = $x / $y;printf &quot;$z has %d places\n&quot;, $z-&gt;places;$z-&gt;places(2) unless $z-&gt;places;print &quot;div of $x by $y is $z\n&quot;;print &quot;square of that is &quot;, $z * $z, &quot;\n&quot;;<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>sum of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 52</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>product of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 480</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>STRFixNum: 3 has 0 places</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>div of STRFixNum: 40 by STRFixNum: 12 is STRFixNum: 3.33</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>square of that is STRFixNum: 11.11</I></CODE></B></CODE></PRE><PCLASS="para">The class itself is shown in <ACLASS="xref"HREF="ch13_15.htm#ch13-16079"TITLE="FixNum">Example 13.2</A>. It only overloads the addition, multiplication, and division operations for math operators. Other operators are the spaceship operator, which handles all comparisons, the string-interpolation operator, and the numeric conversion operator. The string interpolation operator is given a distinctive look for debugging purposes.</P><DIVCLASS="example"><H4CLASS="example"><ACLASS="title"NAME="ch13-16079">Example 13.2: FixNum</A></H4><PRECLASS="programlisting">package FixNum;use strict;my $PLACES = 0;sub new {    my $proto   = shift;    my $class   = ref($proto) || $proto;    my $parent  = ref($proto) &amp;&amp; $proto;    my $v = shift;    my $self = {        VALUE  =&gt; $v,        PLACES =&gt; undef,    };     if ($parent &amp;&amp; defined $parent-&gt;{PLACES}) {        $self-&gt;{PLACES} = $parent-&gt;{PLACES};    } elsif ($v =~ /(\.\d*)/) {        $self-&gt;{PLACES} = length($1) - 1;    }  else {        $self-&gt;{PLACES} = 0;    }     return bless $self, $class;} sub places {    my $proto = shift;    my $self  = ref($proto) &amp;&amp; $proto;    my $type  = ref($proto) || $proto;    if (@_) {        my $places = shift;        ($self ? $self-&gt;{PLACES} : $PLACES) = $places;    }     return $self ? $self-&gt;{PLACES} : $PLACES;} sub _max { $_[0] &gt; $_[1] ? $_[0] : $_[1] } use overload '+'    =&gt; \&amp;add,             '*'    =&gt; \&amp;multiply,             '/'    =&gt; \&amp;divide,             '&lt;=&gt;'  =&gt; \&amp;spaceship,             '&quot;&quot;'   =&gt; \&amp;as_string,             '0+'   =&gt; \&amp;as_number;sub add {    my ($this, $that, $flipped) = @_;    my $result = $this-&gt;new( $this-&gt;{VALUE} + $that-&gt;{VALUE} );    $result-&gt;places( _max($this-&gt;{PLACES}, $that-&gt;{PLACES} ));    return $result;} sub multiply {    my ($this, $that, $flipped) = @_;    my $result = $this-&gt;new( $this-&gt;{VALUE} * $that-&gt;{VALUE} );    $result-&gt;places( _max($this-&gt;{PLACES}, $that-&gt;{PLACES} ));    return $result;} sub divide {    my ($this, $that, $flipped) = @_;    my $result = $this-&gt;new( $this-&gt;{VALUE} / $that-&gt;{VALUE} );    $result-&gt;places( _max($this-&gt;{PLACES}, $that-&gt;{PLACES} ));    return $result;} sub as_string {    my $self = shift;    return sprintf(&quot;STR%s: %.*f&quot;, ref($self),         defined($self-&gt;{PLACES}) ? $self-&gt;{PLACES} : $PLACES,            $self-&gt;{VALUE}); } sub as_number {    my $self = shift;    return $self-&gt;{VALUE};}     sub spaceship {    my ($this, $that, $flipped) = @_;    $this-&gt;{VALUE} &lt;=&gt; $that-&gt;{VALUE};} <ACLASS="indexterm"NAME="ch13-idx-1000005805-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000005805-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000005805-2"></A><ACLASS="indexterm"NAME="ch13-idx-1000005805-3"></A><ACLASS="indexterm"NAME="ch13-idx-1000005805-4"></A>1;<ACLASS="indexterm"NAME="ch13-idx-1000005806-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000005806-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000005806-2"></A></PRE></DIV></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-2247">See Also</A></H3><PCLASS="para">The documentation for the standard <CODECLASS="literal">use</CODE> <CODECLASS="literal">overload</CODE> pragma and the Math::BigInt and Math::Complex modules, also in <ACLASS="olink"HREF="../prog/ch07_01.htm">Chapter 7</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_14.htm"TITLE="13.13. Coping with Circular Data Structures"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.13. Coping with Circular Data Structures"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_16.htm"TITLE="13.15. Creating Magic Variables with tie"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.15. Creating Magic Variables with tie"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">13.13. Coping with Circular Data Structures</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">13.15. Creating Magic Variables with tie</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

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