76
79
<div id="centerContent">
77
80
<div id="contentHeader">
78
81
<div id="contentHeaderLeft"><a href="#" onClick="showLeft()">Show navigation</a></div>
79
<div id="contentHeaderCentre">-- Perl 5.8.8 documentation --</div>
82
<div id="contentHeaderCentre">-- Perl 5.10.0 documentation --</div>
80
83
<div id="contentHeaderRight"><a href="#" onClick="showRight()">Show toolbar</a></div>
82
85
<div id="breadCrumbs"><a href="index.html">Home</a> > <a href="index-pragmas.html">Pragmas</a> > overload</div>
83
86
<script language="JavaScript">fromSearch();</script>
84
<div id="contentBody"><div class="title_container"><div class="page_title">overload</div></div><ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><ul><li><a href="#Declaration-of-overloaded-functions">Declaration of overloaded functions</a><li><a href="#Calling-Conventions-for-Binary-Operations">Calling Conventions for Binary Operations</a><li><a href="#Calling-Conventions-for-Unary-Operations">Calling Conventions for Unary Operations</a><li><a href="#Calling-Conventions-for-Mutators">Calling Conventions for Mutators</a><li><a href="#Overloadable-Operations">Overloadable Operations</a><li><a href="#Inheritance-and-overloading">Inheritance and overloading</a></ul><li><a href="#SPECIAL-SYMBOLS-FOR-'use-overload'">SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
85
</a><ul><li><a href="#Last-Resort">Last Resort</a><li><a href="#Fallback">Fallback</a><li><a href="#Copy-Constructor">Copy Constructor</a></ul><li><a href="#MAGIC-AUTOGENERATION">MAGIC AUTOGENERATION</a><li><a href="#Losing-overloading">Losing overloading</a><li><a href="#Run-time-Overloading">Run-time Overloading</a><li><a href="#Public-functions">Public functions</a><li><a href="#Overloading-constants">Overloading constants</a><li><a href="#IMPLEMENTATION">IMPLEMENTATION</a><li><a href="#Metaphor-clash">Metaphor clash</a><li><a href="#Cookbook">Cookbook</a><ul><li><a href="#Two-face-scalars">Two-face scalars</a><li><a href="#Two-face-references">Two-face references</a><li><a href="#Symbolic-calculator">Symbolic calculator</a><li><a href="#_Really_-symbolic-calculator"><i>Really</i> symbolic calculator</a></ul><li><a href="#AUTHOR">AUTHOR</a><li><a href="#DIAGNOSTICS">DIAGNOSTICS</a><li><a href="#BUGS">BUGS</a></ul><a name="NAME"></a><h1>NAME</h1>
87
<div id="contentBody"><div class="title_container"><div class="page_title">overload</div></div><ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><ul><li><a href="#Declaration-of-overloaded-functions">Declaration of overloaded functions</a><li><a href="#Calling-Conventions-for-Binary-Operations">Calling Conventions for Binary Operations</a><li><a href="#Calling-Conventions-for-Unary-Operations">Calling Conventions for Unary Operations</a><li><a href="#Calling-Conventions-for-Mutators">Calling Conventions for Mutators</a><li><a href="#Overloadable-Operations">Overloadable Operations</a><li><a href="#Inheritance-and-overloading">Inheritance and overloading</a></ul><li><a href="#SPECIAL-SYMBOLS-FOR-'use-overload'">SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
88
</a><ul><li><a href="#Last-Resort">Last Resort</a><li><a href="#Fallback">Fallback</a><li><a href="#Smart-Match">Smart Match</a><li><a href="#Copy-Constructor">Copy Constructor</a></ul><li><a href="#MAGIC-AUTOGENERATION">MAGIC AUTOGENERATION</a><li><a href="#Minimal-set-of-overloaded-operations">Minimal set of overloaded operations</a><li><a href="#Losing-overloading">Losing overloading</a><li><a href="#Run-time-Overloading">Run-time Overloading</a><li><a href="#Public-functions">Public functions</a><li><a href="#Overloading-constants">Overloading constants</a><li><a href="#IMPLEMENTATION">IMPLEMENTATION</a><li><a href="#Metaphor-clash">Metaphor clash</a><li><a href="#Cookbook">Cookbook</a><ul><li><a href="#Two-face-scalars">Two-face scalars</a><li><a href="#Two-face-references">Two-face references</a><li><a href="#Symbolic-calculator">Symbolic calculator</a><li><a href="#_Really_-symbolic-calculator"><i>Really</i> symbolic calculator</a></ul><li><a href="#AUTHOR">AUTHOR</a><li><a href="#DIAGNOSTICS">DIAGNOSTICS</a><li><a href="#BUGS">BUGS</a></ul><a name="NAME"></a><h1>NAME</h1>
86
89
<p>overload - Package for overloading Perl operations</p>
87
90
<a name="SYNOPSIS"></a><h1>SYNOPSIS</h1>
88
91
<pre class="verbatim"><a name="package-SomeThing"></a> package <span class="i">SomeThing</span><span class="sc">;</span></pre>
89
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a>
92
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span>
90
93
<span class="q">'+'</span> <span class="cm">=></span> \<span class="i">&myadd</span><span class="cm">,</span>
91
94
<span class="q">'-'</span> <span class="cm">=></span> \<span class="i">&mysub</span><span class="sc">;</span>
92
95
<span class="c"># etc</span>
94
97
<pre class="verbatim"><a name="package-main"></a> package <span class="i">main</span><span class="sc">;</span>
95
<span class="i">$a</span> = new SomeThing <span class="n">57</span><span class="sc">;</span>
98
<span class="i">$a</span> = <span class="w">new</span> <span class="w">SomeThing</span> <span class="n">57</span><span class="sc">;</span>
96
99
<span class="i">$b</span>=<span class="n">5</span>+<span class="i">$a</span><span class="sc">;</span>
98
if <span class="s">(</span>overload::Overloaded <span class="i">$b</span><span class="s">)</span> <span class="s">{</span>...<span class="s">}</span>
101
if <span class="s">(</span><span class="w">overload::Overloaded</span> <span class="i">$b</span><span class="s">)</span> <span class="s">{</span>...<span class="s">}</span>
100
<span class="i">$strval</span> = overload::StrVal <span class="i">$b</span><span class="sc">;</span></pre>
103
<span class="i">$strval</span> = <span class="w">overload::StrVal</span> <span class="i">$b</span><span class="sc">;</span></pre>
101
104
<a name="DESCRIPTION"></a><h1>DESCRIPTION</h1>
102
105
<a name="Declaration-of-overloaded-functions"></a><h2>Declaration of overloaded functions</h2>
103
106
<p>The compilation directive</p>
104
107
<pre class="verbatim"><a name="package-Number"></a> package <span class="i">Number</span><span class="sc">;</span>
105
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a>
108
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span>
106
109
<span class="q">"+"</span> <span class="cm">=></span> \<span class="i">&add</span><span class="cm">,</span>
107
110
<span class="q">"*="</span> <span class="cm">=></span> <span class="q">"muas"</span><span class="sc">;</span></pre>
108
111
<p>declares function Number::add() for addition, and method muas() in
109
the "class" <code class="inline">Number</code>
112
the "class" <code class="inline"><span class="w">Number</span></code>
110
113
(or one of its base classes)
111
114
for the assignment form <code class="inline"><span class="i">*=</span></code>
112
115
of multiplication.</p>
116
119
subroutine, a reference to a subroutine, or an anonymous subroutine
117
120
will all work. Note that values specified as strings are
118
121
interpreted as methods, not subroutines. Legal keys are listed below.</p>
119
<p>The subroutine <code class="inline">add</code>
122
<p>The subroutine <code class="inline"><span class="w">add</span></code>
120
123
will be called to execute <code class="inline"><span class="i">$a</span>+<span class="i">$b</span></code>
122
is a reference to an object blessed into the package <code class="inline">Number</code>
125
is a reference to an object blessed into the package <code class="inline"><span class="w">Number</span></code>
124
127
not an object from a package with defined mathemagic addition, but $b is a
125
reference to a <code class="inline">Number</code>
128
reference to a <code class="inline"><span class="w">Number</span></code>
126
129
. It can also be called in other situations, like
127
130
<code class="inline"><span class="i">$a</span>+=<span class="n">7</span></code>
128
131
, or <code class="inline"><span class="i">$a</span>++</code>
133
136
above declaration would also trigger overloading of <code class="inline">+</code>
134
137
and <code class="inline"><span class="i">*=</span></code>
136
all the packages which inherit from <code class="inline">Number</code>
139
all the packages which inherit from <code class="inline"><span class="w">Number</span></code>
138
141
<a name="Calling-Conventions-for-Binary-Operations"></a><h2>Calling Conventions for Binary Operations</h2>
139
<p>The functions specified in the <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> ...</code>
142
<p>The functions specified in the <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> ...</code>
140
143
directive are called
141
144
with three (in one particular case with four, see <a href="#Last-Resort">"Last Resort"</a>)
142
145
arguments. If the corresponding operation is binary, then the first
205
208
<p><b>Warning.</b> Due to the presence of assignment versions of operations,
206
209
routines which may be called in assignment context may create
207
210
self-referential structures. Currently Perl will not free self-referential
208
structures until cycles are <code class="inline">explicitly</code>
211
structures until cycles are <code class="inline"><span class="w">explicitly</span></code>
209
212
broken. You may get problems
210
213
when traversing your structures too.</p>
212
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> <span class="q">'+'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span> \<span class="i">$_</span>[<span class="n">0</span>]<span class="cm">,</span> \<span class="i">$_</span>[<span class="n">1</span>] <span class="s">]</span> <span class="s">}</span><span class="sc">;</span></pre>
215
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="q">'+'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span> \<span class="i">$_</span>[<span class="n">0</span>]<span class="cm">,</span> \<span class="i">$_</span>[<span class="n">1</span>] <span class="s">]</span> <span class="s">}</span><span class="sc">;</span></pre>
213
216
<p>is asking for trouble, since for code <code class="inline"><span class="i">$obj</span> += <span class="i">$foo</span></code>
215
218
is called as <code class="inline"><span class="i">$obj</span> = <span class="i">add</span><span class="s">(</span><span class="i">$obj</span><span class="cm">,</span> <span class="i">$foo</span><span class="cm">,</span> <a class="l_k" href="functions/undef.html">undef</a><span class="s">)</span></code>
254
257
<p>If the corresponding "spaceship" variant is available, it can be
255
258
used to substitute for the missing operation. During <code class="inline"><a class="l_k" href="functions/sort.html">sort</a></code>ing
256
259
arrays, <code class="inline">cmp</code>
257
is used to compare values subject to <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
260
is used to compare values subject to <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
260
263
<li><a name="*-_Bit-operations_"></a><b><i>Bit operations</i></b>
261
<pre class="verbatim"> <span class="q">"&"</span><span class="cm">,</span> <span class="q">"^"</span><span class="cm">,</span> <span class="q">"|"</span><span class="cm">,</span> <span class="q">"neg"</span><span class="cm">,</span> <span class="q">"!"</span><span class="cm">,</span> <span class="q">"~"</span><span class="cm">,</span></pre>
262
<p><code class="inline">neg</code>
263
stands for unary minus. If the method for <code class="inline">neg</code>
264
<pre class="verbatim"> <span class="q">"&"</span><span class="cm">,</span> <span class="q">"&="</span><span class="cm">,</span> <span class="q">"^"</span><span class="cm">,</span> <span class="q">"^="</span><span class="cm">,</span> <span class="q">"|"</span><span class="cm">,</span> <span class="q">"|="</span><span class="cm">,</span> <span class="q">"neg"</span><span class="cm">,</span> <span class="q">"!"</span><span class="cm">,</span> <span class="q">"~"</span><span class="cm">,</span></pre>
265
<p><code class="inline"><span class="w">neg</span></code>
266
stands for unary minus. If the method for <code class="inline"><span class="w">neg</span></code>
265
268
specified, it can be autogenerated using the method for
266
269
subtraction. If the method for <code class="inline">!</code>
267
270
is not specified, it can be
268
autogenerated using the methods for <code class="inline">bool</code>
271
autogenerated using the methods for <code class="inline"><span class="w">bool</span></code>
269
272
, or <code class="inline"><span class="q">""</span></code>
270
273
, or <code class="inline"><span class="n">0</span>+</code>
275
<p>The same remarks in <a href="#Arithmetic-operations">"Arithmetic operations"</a> about
276
assignment-variants and autogeneration apply for
277
bit operations <code class="inline"><span class="q">"&"</span></code>
278
, <code class="inline"><span class="q">"^"</span></code>
279
, and <code class="inline"><span class="q">"|"</span></code>
273
282
<li><a name="*-_Increment-and-decrement_"></a><b><i>Increment and decrement</i></b>
274
283
<pre class="verbatim"> <span class="q">"++"</span><span class="cm">,</span> <span class="q">"--"</span><span class="cm">,</span></pre>
289
298
<li><a name="*-_Boolean%2c-string-and-numeric-conversion_"></a><b><i>Boolean, string and numeric conversion</i></b>
290
299
<pre class="verbatim"> <span class="q">'bool'</span><span class="cm">,</span> <span class="q">'""'</span><span class="cm">,</span> <span class="q">'0+'</span><span class="cm">,</span></pre>
291
300
<p>If one or two of these operations are not overloaded, the remaining ones can
292
be used instead. <code class="inline">bool</code>
301
be used instead. <code class="inline"><span class="w">bool</span></code>
293
302
is used in the flow control operators
294
303
(like <code class="inline">while</code>
295
304
) and for the ternary <code class="inline">?:</code> operation. These functions can
325
334
<li><a name="*-_Special_"></a><b><i>Special</i></b>
326
<pre class="verbatim"> <span class="q">"nomethod"</span><span class="cm">,</span> <span class="q">"fallback"</span><span class="cm">,</span> <span class="q">"="</span><span class="cm">,</span></pre>
327
<p>see <a href="http://search.cpan.org/perldoc/SPECIAL SYMBOLS FOR <code class="inline">use overload<#code%3e">"code>" in SPECIAL SYMBOLS FOR <code class="inline">use overload<</a>.</p>
335
<pre class="verbatim"> <span class="q">"nomethod"</span><span class="cm">,</span> <span class="q">"fallback"</span><span class="cm">,</span> <span class="q">"="</span><span class="cm">,</span> <span class="q">"~~"</span><span class="cm">,</span></pre>
336
<p>see <a href="http://search.cpan.org/perldoc/SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions#use.html%22%3euse%3c%2fa%3e-%3cspan-class%3d%22w%22%3eoverload%3c%2fspan%3e%3c%2fcode%3e">"use.html">use</a> <span class="w">overload</span></code>" in SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions</a>.</p>
330
339
<p>See <a href="#Fallback">"Fallback"</a> for an explanation of when a missing method can be
331
340
autogenerated.</p>
332
341
<p>A computer-readable form of the above table is available in the hash
333
342
%overload::ops, with values being space-separated lists of names:</p>
334
<pre class="verbatim"> with_assign <span class="cm">=></span> <span class="q">'+ - * / % ** << >> x .'</span><span class="cm">,</span>
335
assign <span class="cm">=></span> <span class="q">'+= -= *= /= %= **= <<= >>= x= .='</span><span class="cm">,</span>
336
num_comparison <span class="cm">=></span> <span class="q">'< <= > >= == !='</span><span class="cm">,</span>
337
<span class="q">'3way_comparison'</span><span class="cm">=></span> <span class="q">'<=> cmp'</span><span class="cm">,</span>
338
str_comparison <span class="cm">=></span> <span class="q">'lt le gt ge eq ne'</span><span class="cm">,</span>
339
binary <span class="cm">=></span> <span class="q">'& | ^'</span><span class="cm">,</span>
340
unary <span class="cm">=></span> <span class="q">'neg ! ~'</span><span class="cm">,</span>
341
mutators <span class="cm">=></span> <span class="q">'++ --'</span><span class="cm">,</span>
342
func <span class="cm">=></span> <span class="q">'atan2 cos sin exp abs log sqrt'</span><span class="cm">,</span>
343
conversion <span class="cm">=></span> <span class="q">'bool "" 0+'</span><span class="cm">,</span>
344
iterators <span class="cm">=></span> <span class="q">'<>'</span><span class="cm">,</span>
345
dereferencing <span class="cm">=></span> <span class="q">'${} @{} %{} &{} *{}'</span><span class="cm">,</span>
346
special <span class="cm">=></span> <span class="q">'nomethod fallback ='</span></pre>
343
<pre class="verbatim"> <span class="w">with_assign</span> <span class="cm">=></span> <span class="q">'+ - * / % ** << >> x .'</span><span class="cm">,</span>
344
<span class="w">assign</span> <span class="cm">=></span> <span class="q">'+= -= *= /= %= **= <<= >>= x= .='</span><span class="cm">,</span>
345
<span class="w">num_comparison</span> <span class="cm">=></span> <span class="q">'< <= > >= == !='</span><span class="cm">,</span>
346
<span class="q">'3way_comparison'</span><span class="cm">=></span> <span class="q">'<=> cmp'</span><span class="cm">,</span>
347
<span class="w">str_comparison</span> <span class="cm">=></span> <span class="q">'lt le gt ge eq ne'</span><span class="cm">,</span>
348
<span class="w">binary</span> <span class="cm">=></span> <span class="q">'& &= | |= ^ ^='</span><span class="cm">,</span>
349
<span class="w">unary</span> <span class="cm">=></span> <span class="q">'neg ! ~'</span><span class="cm">,</span>
350
<span class="w">mutators</span> <span class="cm">=></span> <span class="q">'++ --'</span><span class="cm">,</span>
351
<span class="w">func</span> <span class="cm">=></span> <span class="q">'atan2 cos sin exp abs log sqrt'</span><span class="cm">,</span>
352
<span class="w">conversion</span> <span class="cm">=></span> <span class="q">'bool "" 0+'</span><span class="cm">,</span>
353
<span class="w">iterators</span> <span class="cm">=></span> <span class="q">'<>'</span><span class="cm">,</span>
354
<span class="w">dereferencing</span> <span class="cm">=></span> <span class="q">'${} @{} %{} &{} *{}'</span><span class="cm">,</span>
355
<span class="w">special</span> <span class="cm">=></span> <span class="q">'nomethod fallback ='</span></pre>
347
356
<a name="Inheritance-and-overloading"></a><h2>Inheritance and overloading</h2>
348
357
<p>Inheritance interacts with overloading in two ways.</p>
350
<li><a name="Strings-as-values-of-'use-overload'-directive"></a><b>Strings as values of <code class="inline">use overload</code> directive</b>
351
<p>If <code class="inline">value</code>
359
<li><a name="Strings-as-values-of-'use-overload'-directive"></a><b>Strings as values of <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
361
<p>If <code class="inline"><span class="w">value</span></code>
353
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> key <span class="cm">=></span> value<span class="sc">;</span></pre>
363
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="w">key</span> <span class="cm">=></span> <span class="w">value</span><span class="sc">;</span></pre>
354
364
<p>is a string, it is interpreted as a method name.</p>
356
366
<li><a name="Overloading-of-an-operation-is-inherited-by-derived-classes"></a><b>Overloading of an operation is inherited by derived classes</b>
359
369
the ancestors. If some method is overloaded in several ancestor, then
360
370
which description will be used is decided by the usual inheritance
362
<p>If <code class="inline">A</code>
363
inherits from <code class="inline"><a class="l_w" href="B.html">B</a></code> and <code class="inline">C</code>
364
(in this order), <code class="inline"><a class="l_w" href="B.html">B</a></code> overloads
372
<p>If <code class="inline"><span class="w">A</span></code>
373
inherits from <code class="inline"><span class="w">B</span></code>
374
and <code class="inline"><span class="w">C</span></code>
375
(in this order), <code class="inline"><span class="w">B</span></code>
365
377
<code class="inline">+</code>
366
378
with <code class="inline">\<span class="i">&D::plus_sub</span></code>
367
, and <code class="inline">C</code>
379
, and <code class="inline"><span class="w">C</span></code>
368
380
overloads <code class="inline">+</code>
369
381
by <code class="inline"><span class="q">"plus_meth"</span></code>
371
then the subroutine <code class="inline">D::plus_sub</code>
383
then the subroutine <code class="inline"><span class="w">D::plus_sub</span></code>
372
384
will be called to implement
373
385
operation <code class="inline">+</code>
374
for an object in package <code class="inline">A</code>
386
for an object in package <code class="inline"><span class="w">A</span></code>
378
<p>Note that since the value of the <code class="inline">fallback</code>
390
<p>Note that since the value of the <code class="inline"><span class="w">fallback</span></code>
379
391
key is not a subroutine,
380
392
its inheritance is not governed by the above rules. In the current
381
implementation, the value of <code class="inline">fallback</code>
393
implementation, the value of <code class="inline"><span class="w">fallback</span></code>
382
394
in the first overloaded
383
395
ancestor is used, but this is accidental and subject to change.</p>
384
<a name="SPECIAL-SYMBOLS-FOR-'use-overload'"></a><h1>SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
396
<a name="SPECIAL-SYMBOLS-FOR-'use-overload'"></a><h1>SPECIAL SYMBOLS FOR <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
386
398
<p>Three keys are recognized by Perl that are not covered by the above
438
450
<p><b>Note.</b> <code class="inline"><span class="q">"fallback"</span></code>
439
451
inheritance via @ISA is not carved in stone
440
452
yet, see <a href="#Inheritance-and-overloading">"Inheritance and overloading"</a>.</p>
453
<a name="Smart-Match"></a><h2>Smart Match</h2>
454
<p>The key <code class="inline"><span class="q">"~~"</span></code>
455
allows you to override the smart matching used by
456
the switch construct. See <a href="feature.html">feature</a>.</p>
441
457
<a name="Copy-Constructor"></a><h2>Copy Constructor</h2>
442
458
<p>The value for <code class="inline"><span class="q">"="</span></code>
443
459
is a reference to a function with three
444
460
arguments, i.e., it looks like the other values in <code class="inline"><a class="l_k" href="functions/use.html">use</a>
445
<a class="l_w" href="overload.html">overload</a></code>
461
<span class="w">overload</span></code>
446
462
. However, it does not overload the Perl assignment
447
463
operator. This would go against Camel hair.</p>
448
464
<p>This operation is called in the situations when a mutator is applied
548
564
<code class="inline"><=></code>
549
565
or <code class="inline">cmp</code>
551
<pre class="verbatim"> <span class="q"><, ></span><span class="cm">,</span> <=<span class="cm">,</span> >=<span class="cm">,</span> ==<span class="cm">,</span> != in terms of <=>
552
lt<span class="cm">,</span> gt<span class="cm">,</span> le<span class="cm">,</span> ge<span class="cm">,</span> eq<span class="cm">,</span> ne in terms of cmp</pre>
567
<pre class="verbatim"> <span class="q"><, ></span><span class="cm">,</span> <=<span class="cm">,</span> >=<span class="cm">,</span> ==<span class="cm">,</span> != <span class="w">in</span> <span class="w">terms</span> <span class="w">of</span> <=>
568
lt<span class="cm">,</span> gt<span class="cm">,</span> le<span class="cm">,</span> ge<span class="cm">,</span> eq<span class="cm">,</span> ne <span class="w">in</span> <span class="w">terms</span> <span class="w">of</span> cmp</pre>
554
570
<li><a name="_Iterator_"></a><b><i>Iterator</i></b>
555
<pre class="verbatim"> <> in terms of builtin operations</pre>
571
<pre class="verbatim"> <> in terms of builtin operations</pre></li>
557
572
<li><a name="_Dereferencing_"></a><b><i>Dereferencing</i></b>
558
573
<pre class="verbatim"> ${} @{} %{} &{} *{} in terms of builtin operations</pre></li>
559
574
<li><a name="_Copy-operator_"></a><b><i>Copy operator</i></b>
561
576
value is a scalar and not a reference.</p>
579
<a name="Minimal-set-of-overloaded-operations"></a><h1>Minimal set of overloaded operations</h1>
580
<p>Since some operations can be automatically generated from others, there is
581
a minimal set of operations that need to be overloaded in order to have
582
the complete set of overloaded operations at one's disposal.
583
Of course, the autogenerated operations may not do exactly what the user
584
expects. See <a href="#MAGIC-AUTOGENERATION">"MAGIC AUTOGENERATION"</a> above. The minimal set is:</p>
585
<pre class="verbatim"> + - <span class="i">* /</span> % <span class="i">**</span> << >> <span class="w">x</span>
587
<span class="i">& |</span> ^ ~
588
<a class="l_k" href="functions/atan2.html">atan2</a> <a class="l_k" href="functions/cos.html">cos</a> <a class="l_k" href="functions/sin.html">sin</a> <a class="l_k" href="functions/exp.html">exp</a> <a class="l_k" href="functions/log.html">log</a> <a class="l_k" href="functions/sqrt.html">sqrt</a> <a class="l_k" href="functions/int.html">int</a></pre>
589
<p>Additionally, you need to define at least one of string, boolean or
590
numeric conversions because any one can be used to emulate the others.
591
The string conversion can also be used to emulate concatenation.</p>
564
592
<a name="Losing-overloading"></a><h1>Losing overloading</h1>
565
593
<p>The restriction for the comparison operation is that even if, for example,
566
594
`<code class="inline">cmp</code>
586
614
<pre class="verbatim"> <a class="l_k" href="functions/eval.html">eval</a> <span class="q">'no overload "+", "--", "<="'</span><span class="sc">;</span></pre>
587
615
<p>though the use of these constructs during run-time is questionable.</p>
588
616
<a name="Public-functions"></a><h1>Public functions</h1>
589
<p>Package <code class="inline"><a class="l_w" href="overload.html">overload</a>.pm</code>
617
<p>Package <code class="inline"><span class="w">overload</span>.<span class="w">pm</span></code>
590
618
provides the following public functions:</p>
592
620
<li><a name="overload%3a%3aStrVal(arg)"></a><b>overload::StrVal(arg)</b>
593
<p>Gives string value of <code class="inline">arg</code>
621
<p>Gives string value of <code class="inline"><span class="w">arg</span></code>
594
622
as in absence of stringify overloading. If you
595
623
are using this to get the address of a reference (useful for checking if two
596
624
references point to the same thing) then you may be better off using
657
685
<a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span>
658
686
<a class="l_k" href="functions/return.html">return</a> unless <span class="i">@_</span><span class="sc">;</span>
659
687
<a class="l_k" href="functions/die.html">die</a> <span class="q">"unknown import: @_"</span> unless <span class="i">@_</span> == <span class="n">1</span> and <span class="i">$_</span>[<span class="n">0</span>] eq <span class="q">':constant'</span><span class="sc">;</span>
660
overload::constant <a class="l_w" href="integer.html">integer</a> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_w" href="Math/BigInt.html">Math::BigInt</a>->new<span class="s">(</span><a class="l_k" href="functions/shift.html">shift</a><span class="s">)</span><span class="s">}</span><span class="sc">;</span>
688
<span class="w">overload::constant</span> <span class="w">integer</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><span class="w">Math::BigInt</span><span class="w">->new</span><span class="s">(</span><a class="l_k" href="functions/shift.html">shift</a><span class="s">)</span><span class="s">}</span><span class="sc">;</span>
661
689
<span class="s">}</span></pre>
662
<p><b>BUGS</b> Currently overloaded-ness of constants does not propagate
663
into <code class="inline"><a class="l_k" href="functions/eval.html">eval</a> <span class="q">'...'</span></code>
665
690
<a name="IMPLEMENTATION"></a><h1>IMPLEMENTATION</h1>
666
691
<p>What follows is subject to change RSN.</p>
667
692
<p>The table of methods for all operations is cached in magic for the
668
693
symbol table hash for the package. The cache is invalidated during
669
processing of <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
670
, <code class="inline"><a class="l_k" href="functions/no.html">no</a> <a class="l_w" href="overload.html">overload</a></code>
694
processing of <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
695
, <code class="inline"><a class="l_k" href="functions/no.html">no</a> <span class="w">overload</span></code>
672
697
definitions, and changes in @ISA. However, this invalidation remains
673
698
unprocessed until the next <code class="inline"><a class="l_k" href="functions/bless.html">bless</a></code>ing into the package. Hence if you
683
708
<p>If an object belongs to a package using overload, it carries a special
684
709
flag. Thus the only speed penalty during arithmetic operations without
685
710
overloading is the checking of this flag.</p>
686
<p>In fact, if <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
711
<p>In fact, if <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
687
712
is not present, there is almost no overhead
688
713
for overloadable operations, so most programs should not suffer
689
714
measurable performance penalties. A considerable effort was made to
690
715
minimize the overhead when overload is used in some package, but the
691
716
arguments in question do not belong to packages using overload. When
692
in doubt, test your speed with <code class="inline"><a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a></code>
717
in doubt, test your speed with <code class="inline"><a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span></code>
693
718
and without it. So far
694
719
there have been no reports of substantial speed degradation if Perl is
695
720
compiled with optimization turned on.</p>
738
763
<p>If some mutator methods are directly applied to the overloaded values,
739
764
one may need to <i>explicitly unlink</i> other values which references the
741
<pre class="verbatim"> <span class="i">$a</span> = new Data <span class="n">23</span><span class="sc">;</span>
766
<pre class="verbatim"> <span class="i">$a</span> = <span class="w">new</span> <span class="w">Data</span> <span class="n">23</span><span class="sc">;</span>
743
768
<span class="i">$b</span> = <span class="i">$a</span><span class="sc">;</span> <span class="c"># $b is "linked" to $a</span>
745
770
<span class="i">$a</span> = <span class="i">$a</span><span class="i">->clone</span><span class="sc">;</span> <span class="c"># Unlink $b from $a</span>
746
771
<span class="i">$a</span><span class="i">->increment_by</span><span class="s">(</span><span class="n">4</span><span class="s">)</span><span class="sc">;</span></pre>
747
772
<p>Note that overloaded access makes this transparent:</p>
748
<pre class="verbatim"> <span class="i">$a</span> = new Data <span class="n">23</span><span class="sc">;</span>
773
<pre class="verbatim"> <span class="i">$a</span> = <span class="w">new</span> <span class="w">Data</span> <span class="n">23</span><span class="sc">;</span>
749
774
<span class="i">$b</span> = <span class="i">$a</span><span class="sc">;</span> <span class="c"># $b is "linked" to $a</span>
750
775
<span class="i">$a</span> += <span class="n">4</span><span class="sc">;</span> <span class="c"># would unlink $b automagically</span></pre>
751
776
<p>However, it would not make</p>
752
<pre class="verbatim"> <span class="i">$a</span> = new Data <span class="n">23</span><span class="sc">;</span>
777
<pre class="verbatim"> <span class="i">$a</span> = <span class="w">new</span> <span class="w">Data</span> <span class="n">23</span><span class="sc">;</span>
753
778
<span class="i">$a</span> = <span class="n">4</span><span class="sc">;</span> <span class="c"># Now $a is a plain 4, not 'Data'</span></pre>
754
779
<p>preserve "objectness" of $a. But Perl <i>has</i> a way to make assignments
755
780
to an object do whatever you want. It is just not the overload, but
765
790
<pre class="verbatim"><a name="package-two_face"></a> package <span class="i">two_face</span><span class="sc">;</span> <span class="c"># Scalars with separate string and</span>
766
791
<span class="c"># numeric values.</span>
767
792
<a name="new"></a> sub <span class="m">new</span> <span class="s">{</span> <a class="l_k" href="functions/my.html">my</a> <span class="i">$p</span> = <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span> <a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span><span class="i">@_</span><span class="s">]</span><span class="cm">,</span> <span class="i">$p</span> <span class="s">}</span>
768
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="cm">,</span> <span class="q">'0+'</span> <span class="cm">=></span> \<span class="i">&num</span><span class="cm">,</span> fallback <span class="cm">=></span> <span class="n">1</span><span class="sc">;</span>
793
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="cm">,</span> <span class="q">'0+'</span> <span class="cm">=></span> \<span class="i">&num</span><span class="cm">,</span> <span class="w">fallback</span> <span class="cm">=></span> <span class="n">1</span><span class="sc">;</span>
769
794
<a name="num"></a> sub <span class="m">num</span> <span class="s">{</span><a class="l_k" href="functions/shift.html">shift</a>->[<span class="n">1</span>]<span class="s">}</span>
770
795
<a name="str"></a> sub <span class="m">str</span> <span class="s">{</span><a class="l_k" href="functions/shift.html">shift</a>->[<span class="n">0</span>]<span class="s">}</span></pre>
771
796
<p>Use it as follows:</p>
772
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> two_face<span class="sc">;</span>
773
<a class="l_k" href="functions/my.html">my</a> <span class="i">$seven</span> = new two_face <span class="s">(</span><span class="q">"vii"</span><span class="cm">,</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
797
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> <span class="w">two_face</span><span class="sc">;</span>
798
<a class="l_k" href="functions/my.html">my</a> <span class="i">$seven</span> = <span class="w">new</span> <span class="w">two_face</span> <span class="s">(</span><span class="q">"vii"</span><span class="cm">,</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
774
799
<a class="l_k" href="functions/printf.html">printf</a> <span class="q">"seven=$seven, seven=%d, eight=%d\n"</span><span class="cm">,</span> <span class="i">$seven</span><span class="cm">,</span> <span class="i">$seven</span>+<span class="n">1</span><span class="sc">;</span>
775
800
<a class="l_k" href="functions/print.html">print</a> <span class="q">"seven contains `i'\n"</span> if <span class="i">$seven</span> =~ <span class="q">/i/</span><span class="sc">;</span></pre>
776
801
<p>(The second line creates a scalar which has both a string value, and a
778
803
<pre class="verbatim"> seven=vii, seven=7, eight=8
779
804
seven contains `i'</pre><a name="Two-face-references"></a><h2>Two-face references</h2>
780
805
<p>Suppose you want to create an object which is accessible as both an
781
array reference and a hash reference, similar to the
782
<a href="perlref.html#Pseudo-hashes%3a-Using-an-array-as-a-hash">pseudo-hash</a>
783
builtin Perl type. Let's make it better than a pseudo-hash by
784
allowing index 0 to be treated as a normal element.</p>
806
array reference and a hash reference.</p>
785
807
<pre class="verbatim"><a name="package-two_refs"></a> package <span class="i">two_refs</span><span class="sc">;</span>
786
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> <span class="q">'%{}'</span> <span class="cm">=></span> \<span class="i">&gethash</span><span class="cm">,</span> <span class="q">'@{}'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$</span> {<a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span>} <span class="s">}</span><span class="sc">;</span>
808
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="q">'%{}'</span> <span class="cm">=></span> \<span class="i">&gethash</span><span class="cm">,</span> <span class="q">'@{}'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$</span> {<a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span>} <span class="s">}</span><span class="sc">;</span>
787
809
<a name="new"></a> sub <span class="m">new</span> <span class="s">{</span>
788
810
<a class="l_k" href="functions/my.html">my</a> <span class="i">$p</span> = <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span>
789
811
<a class="l_k" href="functions/bless.html">bless</a> \ <span class="s">[</span><span class="i">@_</span><span class="s">]</span><span class="cm">,</span> <span class="i">$p</span><span class="sc">;</span>
811
833
<span class="i">$$self</span>->[<span class="i">$key</span>]<span class="sc">;</span>
812
834
<span class="s">}</span></pre>
813
835
<p>Now one can access an object using both the array and hash syntax:</p>
814
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">$bar</span> = new two_refs <span class="n">3</span><span class="cm">,</span><span class="n">4</span><span class="cm">,</span><span class="n">5</span><span class="cm">,</span><span class="n">6</span><span class="sc">;</span>
836
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">$bar</span> = <span class="w">new</span> <span class="w">two_refs</span> <span class="n">3</span><span class="cm">,</span><span class="n">4</span><span class="cm">,</span><span class="n">5</span><span class="cm">,</span><span class="n">6</span><span class="sc">;</span>
815
837
<span class="i">$bar</span>->[<span class="n">2</span>] = <span class="n">11</span><span class="sc">;</span>
816
<span class="i">$bar</span>->{two} == <span class="n">11</span> or <a class="l_k" href="functions/die.html">die</a> <span class="q">'bad hash fetch'</span><span class="sc">;</span></pre>
838
<span class="i">$bar</span>->{<span class="w">two</span>} == <span class="n">11</span> or <a class="l_k" href="functions/die.html">die</a> <span class="q">'bad hash fetch'</span><span class="sc">;</span></pre>
817
839
<p>Note several important features of this example. First of all, the
818
840
<i>actual</i> type of $bar is a scalar reference, and we do not overload
819
841
the scalar dereference. Thus we can get the <i>actual</i> non-overloaded
840
862
<p>To remove creation of the tied hash on each access, one may an extra
841
863
level of indirection which allows a non-circular structure of references:</p>
842
864
<pre class="verbatim"><a name="package-two_refs1"></a> package <span class="i">two_refs1</span><span class="sc">;</span>
843
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> <span class="q">'%{}'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$</span>{<a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span>}->[<span class="n">1</span>] <span class="s">}</span><span class="cm">,</span>
865
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="q">'%{}'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$</span>{<a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span>}->[<span class="n">1</span>] <span class="s">}</span><span class="cm">,</span>
844
866
<span class="q">'@{}'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="i">$</span>{<a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span>}->[<span class="n">0</span>] <span class="s">}</span><span class="sc">;</span>
845
867
<a name="new"></a> sub <span class="m">new</span> <span class="s">{</span>
846
868
<a class="l_k" href="functions/my.html">my</a> <span class="i">$p</span> = <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span>
892
914
<a name="Symbolic-calculator"></a><h2>Symbolic calculator</h2>
893
915
<p>Put this in <i>symbolic.pm</i> in your Perl library directory:</p>
894
916
<pre class="verbatim"><a name="package-symbolic"></a> package <span class="i">symbolic</span><span class="sc">;</span> <span class="c"># Primitive symbolic calculator</span>
895
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> nomethod <span class="cm">=></span> \<span class="i">&wrap</span><span class="sc">;</span></pre>
917
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="w">nomethod</span> <span class="cm">=></span> \<span class="i">&wrap</span><span class="sc">;</span></pre>
896
918
<pre class="verbatim"><a name="new"></a> sub <span class="m">new</span> <span class="s">{</span> <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span> <a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span><span class="q">'n'</span><span class="cm">,</span> <span class="i">@_</span><span class="s">]</span> <span class="s">}</span>
897
919
<a name="wrap"></a> sub <span class="m">wrap</span> <span class="s">{</span>
898
920
<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$obj</span><span class="cm">,</span> <span class="i">$other</span><span class="cm">,</span> <span class="i">$inv</span><span class="cm">,</span> <span class="i">$meth</span><span class="s">)</span> = <span class="i">@_</span><span class="sc">;</span>
900
922
<a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span><span class="i">$meth</span><span class="cm">,</span> <span class="i">$obj</span><span class="cm">,</span> <span class="i">$other</span><span class="s">]</span><span class="sc">;</span>
901
923
<span class="s">}</span></pre>
902
924
<p>This module is very unusual as overloaded modules go: it does not
903
provide any usual overloaded operators, instead it provides the <a href="#Last-Resort">"Last Resort"</a> operator <code class="inline">nomethod</code>
925
provide any usual overloaded operators, instead it provides the <a href="#Last-Resort">"Last Resort"</a> operator <code class="inline"><span class="w">nomethod</span></code>
904
926
. In this example the corresponding
905
927
subroutine returns an object which encapsulates operations done over
906
the objects: <code class="inline">new symbolic <span class="n">3</span></code>
928
the objects: <code class="inline"><span class="w">new</span> <span class="w">symbolic</span> <span class="n">3</span></code>
907
929
contains <code class="inline"><span class="s">[</span><span class="q">'n'</span><span class="cm">,</span> <span class="n">3</span><span class="s">]</span></code>
908
, <code class="inline"><span class="n">2</span> + new
909
symbolic <span class="n">3</span></code>
930
, <code class="inline"><span class="n">2</span> + <span class="w">new</span>
931
<span class="w">symbolic</span> <span class="n">3</span></code>
910
932
contains <code class="inline"><span class="s">[</span><span class="q">'+'</span><span class="cm">,</span> <span class="n">2</span><span class="cm">,</span> <span class="s">[</span><span class="q">'n'</span><span class="cm">,</span> <span class="n">3</span><span class="s">]</span><span class="s">]</span></code>
912
934
<p>Here is an example of the script which "calculates" the side of
913
935
circumscribed octagon using the above package:</p>
914
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> symbolic<span class="sc">;</span>
936
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> <span class="w">symbolic</span><span class="sc">;</span>
915
937
<a class="l_k" href="functions/my.html">my</a> <span class="i">$iter</span> = <span class="n">1</span><span class="sc">;</span> <span class="c"># 2**($iter+2) = 8</span>
916
<a class="l_k" href="functions/my.html">my</a> <span class="i">$side</span> = new symbolic <span class="n">1</span><span class="sc">;</span>
938
<a class="l_k" href="functions/my.html">my</a> <span class="i">$side</span> = <span class="w">new</span> <span class="w">symbolic</span> <span class="n">1</span><span class="sc">;</span>
917
939
<a class="l_k" href="functions/my.html">my</a> <span class="i">$cnt</span> = <span class="i">$iter</span><span class="sc">;</span></pre>
918
940
<pre class="verbatim"> while <span class="s">(</span><span class="i">$cnt</span>--<span class="s">)</span> <span class="s">{</span>
919
941
<span class="i">$side</span> = <span class="s">(</span><a class="l_k" href="functions/sqrt.html">sqrt</a><span class="s">(</span><span class="n">1</span> + <span class="i">$side</span>**<span class="n">2</span><span class="s">)</span> - <span class="n">1</span><span class="s">)</span>/<span class="i">$side</span><span class="sc">;</span>
924
946
<a class="l_k" href="functions/undef.html">undef</a><span class="s">]</span><span class="cm">,</span> <span class="n">1</span><span class="s">]</span><span class="cm">,</span> <span class="s">[</span><span class="q">'n'</span><span class="cm">,</span> <span class="n">1</span><span class="s">]</span><span class="s">]</span></pre>
925
947
<p>Note that while we obtained this value using a nice little script,
926
948
there is no simple way to <i>use</i> this value. In fact this value may
927
be inspected in debugger (see <a href="perldebug.html">perldebug</a>), but ony if
928
<code class="inline">bareStringify</code>
929
<b>O</b>ption is set, and not via <code class="inline">p</code>
949
be inspected in debugger (see <a href="perldebug.html">perldebug</a>), but only if
950
<code class="inline"><span class="w">bareStringify</span></code>
951
<b>O</b>ption is set, and not via <code class="inline"><span class="w">p</span></code>
931
953
<p>If one attempts to print this value, then the overloaded operator
932
954
<code class="inline"><span class="q">""</span></code>
933
will be called, which will call <code class="inline">nomethod</code>
955
will be called, which will call <code class="inline"><span class="w">nomethod</span></code>
935
957
result of this operator will be stringified again, but this result is
936
again of type <code class="inline">symbolic</code>
958
again of type <code class="inline"><span class="w">symbolic</span></code>
937
959
, which will lead to an infinite loop.</p>
938
960
<p>Add a pretty-printer method to the module <i>symbolic.pm</i>:</p>
939
961
<pre class="verbatim"><a name="pretty"></a> sub <span class="m">pretty</span> <span class="s">{</span>
958
980
will look for an overloaded operator <code class="inline">.</code>; if not present, it will
959
981
look for an overloaded operator <code class="inline"><span class="q">""</span></code>
960
982
. Thus it is enough to use</p>
961
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a> nomethod <span class="cm">=></span> \<span class="i">&wrap</span><span class="cm">,</span> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="sc">;</span>
983
<pre class="verbatim"> <a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span> <span class="w">nomethod</span> <span class="cm">=></span> \<span class="i">&wrap</span><span class="cm">,</span> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="sc">;</span>
962
984
<a name="str"></a> sub <span class="m">str</span> <span class="s">{</span>
963
985
<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$meth</span><span class="cm">,</span> <span class="i">$a</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span> = <span class="i">@</span>{+<a class="l_k" href="functions/shift.html">shift</a>}<span class="sc">;</span>
964
986
<span class="i">$a</span> = <span class="q">'u'</span> unless <a class="l_k" href="functions/defined.html">defined</a> <span class="i">$a</span><span class="sc">;</span>
973
995
<p>Something is still amiss: consider the loop variable $cnt of the
974
996
script. It was a number, not an object. We cannot make this value of
975
type <code class="inline">symbolic</code>
997
type <code class="inline"><span class="w">symbolic</span></code>
976
998
, since then the loop will not terminate.</p>
977
999
<p>Indeed, to terminate the cycle, the $cnt should become false.
978
However, the operator <code class="inline">bool</code>
1000
However, the operator <code class="inline"><span class="w">bool</span></code>
979
1001
for checking falsity is overloaded (this
980
1002
time via overloaded <code class="inline"><span class="q">""</span></code>
981
1003
), and returns a long string, thus any object
982
of type <code class="inline">symbolic</code>
1004
of type <code class="inline"><span class="w">symbolic</span></code>
983
1005
is true. To overcome this, we need a way to
984
1006
compare an object to 0. In fact, it is easier to write a numeric
985
1007
conversion routine.</p>
986
1008
<p>Here is the text of <i>symbolic.pm</i> with such a routine added (and
987
1009
slightly modified str()):</p>
988
1010
<pre class="verbatim"><a name="package-symbolic"></a> package <span class="i">symbolic</span><span class="sc">;</span> <span class="c"># Primitive symbolic calculator</span>
989
<a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="overload.html">overload</a>
990
nomethod <span class="cm">=></span> \<span class="i">&wrap</span><span class="cm">,</span> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="cm">,</span> <span class="q">'0+'</span> <span class="cm">=></span> \<span class="i">&num</span><span class="sc">;</span></pre>
1011
<a class="l_k" href="functions/use.html">use</a> <span class="w">overload</span>
1012
<span class="w">nomethod</span> <span class="cm">=></span> \<span class="i">&wrap</span><span class="cm">,</span> <span class="q">'""'</span> <span class="cm">=></span> \<span class="i">&str</span><span class="cm">,</span> <span class="q">'0+'</span> <span class="cm">=></span> \<span class="i">&num</span><span class="sc">;</span></pre>
991
1013
<pre class="verbatim"><a name="new"></a> sub <span class="m">new</span> <span class="s">{</span> <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span> <a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span><span class="q">'n'</span><span class="cm">,</span> <span class="i">@_</span><span class="s">]</span> <span class="s">}</span>
992
1014
<a name="wrap"></a> sub <span class="m">wrap</span> <span class="s">{</span>
993
1015
<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$obj</span><span class="cm">,</span> <span class="i">$other</span><span class="cm">,</span> <span class="i">$inv</span><span class="cm">,</span> <span class="i">$meth</span><span class="s">)</span> = <span class="i">@_</span><span class="sc">;</span>
1003
1025
<span class="q">"[$meth $a]"</span><span class="sc">;</span>
1004
1026
<span class="s">}</span>
1005
1027
<span class="s">}</span>
1006
<a class="l_k" href="functions/my.html">my</a> <span class="i">%subr</span> = <span class="s">(</span> n <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span><span class="cm">,</span>
1007
sqrt <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_k" href="functions/sqrt.html">sqrt</a> <span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span><span class="cm">,</span>
1028
<a class="l_k" href="functions/my.html">my</a> <span class="i">%subr</span> = <span class="s">(</span> <span class="w">n</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span><span class="cm">,</span>
1029
<span class="w">sqrt</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_k" href="functions/sqrt.html">sqrt</a> <span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span><span class="cm">,</span>
1008
1030
<span class="q">'-'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span> - <a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span><span class="s">}</span><span class="cm">,</span>
1009
1031
<span class="q">'+'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span> + <a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span><span class="s">}</span><span class="cm">,</span>
1010
1032
<span class="q">'/'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span> / <a class="l_k" href="functions/shift.html">shift</a><span class="s">(</span><span class="s">)</span><span class="s">}</span><span class="cm">,</span>
1015
1037
<a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$meth</span><span class="cm">,</span> <span class="i">$a</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span> = <span class="i">@</span>{+<a class="l_k" href="functions/shift.html">shift</a>}<span class="sc">;</span>
1016
1038
<a class="l_k" href="functions/my.html">my</a> <span class="i">$subr</span> = <span class="i">$subr</span>{<span class="i">$meth</span>}
1017
1039
or <a class="l_k" href="functions/die.html">die</a> <span class="q">"Do not know how to ($meth) in symbolic"</span><span class="sc">;</span>
1018
<span class="i">$a</span> = <span class="i">$a</span><span class="i">->num</span> if <a class="l_k" href="functions/ref.html">ref</a> <span class="i">$a</span> eq __PACKAGE__<span class="sc">;</span>
1019
<span class="i">$b</span> = <span class="i">$b</span><span class="i">->num</span> if <a class="l_k" href="functions/ref.html">ref</a> <span class="i">$b</span> eq __PACKAGE__<span class="sc">;</span>
1040
<span class="i">$a</span> = <span class="i">$a</span><span class="i">->num</span> if <a class="l_k" href="functions/ref.html">ref</a> <span class="i">$a</span> eq <span class="w">__PACKAGE__</span><span class="sc">;</span>
1041
<span class="i">$b</span> = <span class="i">$b</span><span class="i">->num</span> if <a class="l_k" href="functions/ref.html">ref</a> <span class="i">$b</span> eq <span class="w">__PACKAGE__</span><span class="sc">;</span>
1020
1042
<span class="i">$subr</span>-><span class="s">(</span><span class="i">$a</span><span class="cm">,</span><span class="i">$b</span><span class="s">)</span><span class="sc">;</span>
1021
1043
<span class="s">}</span></pre>
1022
1044
<p>All the work of numeric conversion is done in %subr and num(). Of
1024
1046
example below. Here is the extra-credit question: why do we need an
1025
1047
explicit recursion in num()? (Answer is at the end of this section.)</p>
1026
1048
<p>Use this module like this:</p>
1027
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> symbolic<span class="sc">;</span>
1028
<a class="l_k" href="functions/my.html">my</a> <span class="i">$iter</span> = new symbolic <span class="n">2</span><span class="sc">;</span> <span class="c"># 16-gon</span>
1029
<a class="l_k" href="functions/my.html">my</a> <span class="i">$side</span> = new symbolic <span class="n">1</span><span class="sc">;</span>
1049
<pre class="verbatim"> <a class="l_k" href="functions/require.html">require</a> <span class="w">symbolic</span><span class="sc">;</span>
1050
<a class="l_k" href="functions/my.html">my</a> <span class="i">$iter</span> = <span class="w">new</span> <span class="w">symbolic</span> <span class="n">2</span><span class="sc">;</span> <span class="c"># 16-gon</span>
1051
<a class="l_k" href="functions/my.html">my</a> <span class="i">$side</span> = <span class="w">new</span> <span class="w">symbolic</span> <span class="n">1</span><span class="sc">;</span>
1030
1052
<a class="l_k" href="functions/my.html">my</a> <span class="i">$cnt</span> = <span class="i">$iter</span><span class="sc">;</span></pre>
1031
1053
<pre class="verbatim"> while <span class="s">(</span><span class="i">$cnt</span><span class="s">)</span> <span class="s">{</span>
1032
1054
<span class="i">$cnt</span> = <span class="i">$cnt</span> - <span class="n">1</span><span class="sc">;</span> <span class="c"># Mutator `--' not implemented</span>
1047
1069
<p>To implement most arithmetic operations is easy; one should just use
1048
1070
the tables of operations, and change the code which fills %subr to</p>
1049
1071
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">%subr</span> = <span class="s">(</span> <span class="q">'n'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span> <span class="s">)</span><span class="sc">;</span>
1050
foreach <a class="l_k" href="functions/my.html">my</a> <span class="i">$op</span> <span class="s">(</span><a class="l_k" href="functions/split.html">split</a> <span class="q">" "</span><span class="cm">,</span> <span class="i">$overload::ops</span>{with_assign}<span class="s">)</span> <span class="s">{</span>
1072
foreach <a class="l_k" href="functions/my.html">my</a> <span class="i">$op</span> <span class="s">(</span><a class="l_k" href="functions/split.html">split</a> <span class="q">" "</span><span class="cm">,</span> <span class="i">$overload::ops</span>{<span class="w">with_assign</span>}<span class="s">)</span> <span class="s">{</span>
1051
1073
<span class="i">$subr</span>{<span class="i">$op</span>} = <span class="i">$subr</span>{<span class="q">"$op="</span>} = <a class="l_k" href="functions/eval.html">eval</a> <span class="q">"sub {shift() $op shift()}"</span><span class="sc">;</span>
1052
1074
<span class="s">}</span>
1053
1075
<a class="l_k" href="functions/my.html">my</a> <span class="i">@bins</span> = <span class="q">qw(binary 3way_comparison num_comparison str_comparison)</span><span class="sc">;</span>
1078
1100
<p>To make <code class="inline">++</code>
1079
1101
and <code class="inline">--</code>
1080
1102
work, we need to implement actual mutators,
1081
either directly, or in <code class="inline">nomethod</code>
1103
either directly, or in <code class="inline"><span class="w">nomethod</span></code>
1082
1104
. We continue to do things inside
1083
<code class="inline">nomethod</code>
1105
<code class="inline"><span class="w">nomethod</span></code>
1085
1107
<pre class="verbatim"> if <span class="s">(</span><span class="i">$meth</span> eq <span class="q">'++'</span> or <span class="i">$meth</span> eq <span class="q">'--'</span><span class="s">)</span> <span class="s">{</span>
1086
1108
<span class="i">@$obj</span> = <span class="s">(</span><span class="i">$meth</span><span class="cm">,</span> <span class="s">(</span><a class="l_k" href="functions/bless.html">bless</a> <span class="s">[</span><span class="i">@$obj</span><span class="s">]</span><span class="s">)</span><span class="cm">,</span> <span class="n">1</span><span class="s">)</span><span class="sc">;</span> <span class="c"># Avoid circular reference</span>
1092
1114
<p>instead.</p>
1093
1115
<p>As a final remark, note that one can fill %subr by</p>
1094
1116
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">%subr</span> = <span class="s">(</span> <span class="q">'n'</span> <span class="cm">=></span> <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span><span class="i">$_</span>[<span class="n">0</span>]<span class="s">}</span> <span class="s">)</span><span class="sc">;</span>
1095
foreach <a class="l_k" href="functions/my.html">my</a> <span class="i">$op</span> <span class="s">(</span><a class="l_k" href="functions/split.html">split</a> <span class="q">" "</span><span class="cm">,</span> <span class="i">$overload::ops</span>{with_assign}<span class="s">)</span> <span class="s">{</span>
1117
foreach <a class="l_k" href="functions/my.html">my</a> <span class="i">$op</span> <span class="s">(</span><a class="l_k" href="functions/split.html">split</a> <span class="q">" "</span><span class="cm">,</span> <span class="i">$overload::ops</span>{<span class="w">with_assign</span>}<span class="s">)</span> <span class="s">{</span>
1096
1118
<span class="i">$subr</span>{<span class="i">$op</span>} = <span class="i">$subr</span>{<span class="q">"$op="</span>} = <a class="l_k" href="functions/eval.html">eval</a> <span class="q">"sub {shift() $op shift()}"</span><span class="sc">;</span>
1097
1119
<span class="s">}</span>
1098
1120
<a class="l_k" href="functions/my.html">my</a> <span class="i">@bins</span> = <span class="q">qw(binary 3way_comparison num_comparison str_comparison)</span><span class="sc">;</span>
1134
1156
<span class="i">$#$obj</span> = <span class="n">1</span><span class="sc">;</span>
1135
1157
<span class="i">@$obj</span>->[<span class="n">0</span><span class="cm">,</span><span class="n">1</span>] = <span class="s">(</span><span class="q">'='</span><span class="cm">,</span> <a class="l_k" href="functions/shift.html">shift</a><span class="s">)</span><span class="sc">;</span>
1136
1158
<span class="s">}</span></pre>
1137
<p>to the package <code class="inline">symbolic</code>
1159
<p>to the package <code class="inline"><span class="w">symbolic</span></code>
1138
1160
. After this change one can do</p>
1139
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">$a</span> = new symbolic <span class="n">3</span><span class="sc">;</span>
1140
<a class="l_k" href="functions/my.html">my</a> <span class="i">$b</span> = new symbolic <span class="n">4</span><span class="sc">;</span>
1161
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="i">$a</span> = <span class="w">new</span> <span class="w">symbolic</span> <span class="n">3</span><span class="sc">;</span>
1162
<a class="l_k" href="functions/my.html">my</a> <span class="i">$b</span> = <span class="w">new</span> <span class="w">symbolic</span> <span class="n">4</span><span class="sc">;</span>
1141
1163
<a class="l_k" href="functions/my.html">my</a> <span class="i">$c</span> = <a class="l_k" href="functions/sqrt.html">sqrt</a><span class="s">(</span><span class="i">$a</span>**<span class="n">2</span> + <span class="i">$b</span>**<span class="n">2</span><span class="s">)</span><span class="sc">;</span></pre>
1142
1164
<p>and the numeric value of $c becomes 5. However, after calling</p>
1143
1165
<pre class="verbatim"> <span class="i">$a</span><span class="i">->STORE</span><span class="s">(</span><span class="n">12</span><span class="s">)</span><span class="sc">;</span> <span class="i">$b</span><span class="i">->STORE</span><span class="s">(</span><span class="n">5</span><span class="s">)</span><span class="sc">;</span></pre>
1144
1166
<p>the numeric value of $c becomes 13. There is no doubt now that the module
1145
1167
symbolic provides a <i>symbolic</i> calculator indeed.</p>
1146
1168
<p>To hide the rough edges under the hood, provide a tie()d interface to the
1147
package <code class="inline">symbolic</code>
1169
package <code class="inline"><span class="w">symbolic</span></code>
1148
1170
(compare with <a href="#Metaphor-clash">"Metaphor clash"</a>). Add methods</p>
1149
1171
<pre class="verbatim"><a name="TIESCALAR"></a> sub <span class="m">TIESCALAR</span> <span class="s">{</span> <a class="l_k" href="functions/my.html">my</a> <span class="i">$pack</span> = <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span> <span class="i">$pack</span><span class="i">->new</span><span class="s">(</span><span class="i">@_</span><span class="s">)</span> <span class="s">}</span>
1150
1172
<a name="FETCH"></a> sub <span class="m">FETCH</span> <span class="s">{</span> <a class="l_k" href="functions/shift.html">shift</a> <span class="s">}</span>
1160
1182
<pre class="verbatim"><a name="vars"></a> sub <span class="m">vars</span> <span class="s">{</span> <a class="l_k" href="functions/my.html">my</a> <span class="i">$p</span> = <a class="l_k" href="functions/shift.html">shift</a><span class="sc">;</span> <a class="l_k" href="functions/tie.html">tie</a><span class="s">(</span><span class="i">$_</span><span class="cm">,</span> <span class="i">$p</span><span class="s">)</span><span class="cm">,</span> <span class="i">$_</span><span class="i">->nop</span> foreach <span class="i">@_</span><span class="sc">;</span> <span class="s">}</span></pre>
1162
1184
<pre class="verbatim"> <a class="l_k" href="functions/my.html">my</a> <span class="s">(</span><span class="i">$a</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span><span class="sc">;</span>
1163
symbolic->vars<span class="s">(</span><span class="i">$a</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span><span class="sc">;</span>
1185
<span class="w">symbolic</span><span class="w">->vars</span><span class="s">(</span><span class="i">$a</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span><span class="sc">;</span>
1164
1186
<a class="l_k" href="functions/my.html">my</a> <span class="i">$c</span> = <a class="l_k" href="functions/sqrt.html">sqrt</a><span class="s">(</span><span class="i">$a</span>**<span class="n">2</span> + <span class="i">$b</span>**<span class="n">2</span><span class="s">)</span><span class="sc">;</span></pre>
1165
1187
<pre class="verbatim"> <span class="i">$a</span> = <span class="n">3</span><span class="sc">;</span> <span class="i">$b</span> = <span class="n">4</span><span class="sc">;</span>
1166
1188
<a class="l_k" href="functions/printf.html">printf</a> <span class="q">"c5 %s=%f\n"</span><span class="cm">,</span> <span class="i">$c</span><span class="cm">,</span> <span class="i">$c</span><span class="sc">;</span></pre>
1178
1200
this overloading). Say, if <code class="inline">eq</code>
1179
1201
is overloaded, then the method <code class="inline">(eq</code>
1180
1202
is shown by debugger. The method <code class="inline"><span class="s">(</span><span class="s">)</span></code>
1181
corresponds to the <code class="inline">fallback</code>
1203
corresponds to the <code class="inline"><span class="w">fallback</span></code>
1183
1205
key (in fact a presence of this method shows that this package has
1184
overloading enabled, and it is what is used by the <code class="inline">Overloaded</code>
1206
overloading enabled, and it is what is used by the <code class="inline"><span class="w">Overloaded</span></code>
1186
function of module <code class="inline"><a class="l_w" href="overload.html">overload</a></code>).</p>
1208
function of module <code class="inline"><span class="w">overload</span></code>
1187
1210
<p>The module might issue the following warnings:</p>
1189
1212
<li><a name="Odd-number-of-arguments-for-overload%3a%3aconstant"></a><b>Odd number of arguments for overload::constant</b>