diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/mageia-cauldron/man3pm/overload.3pm | |
parent | Initial commit. (diff) | |
download | manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip |
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/mageia-cauldron/man3pm/overload.3pm')
-rw-r--r-- | upstream/mageia-cauldron/man3pm/overload.3pm | 1612 |
1 files changed, 1612 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man3pm/overload.3pm b/upstream/mageia-cauldron/man3pm/overload.3pm new file mode 100644 index 00000000..be6c917a --- /dev/null +++ b/upstream/mageia-cauldron/man3pm/overload.3pm @@ -0,0 +1,1612 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "overload 3pm" +.TH overload 3pm 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +overload \- Package for overloading Perl operations +.SH SYNOPSIS +.IX Header "SYNOPSIS" +.Vb 1 +\& package SomeThing; +\& +\& use overload +\& \*(Aq+\*(Aq => \e&myadd, +\& \*(Aq\-\*(Aq => \e&mysub; +\& # etc +\& ... +\& +\& package main; +\& $a = SomeThing\->new( 57 ); +\& $b = 5 + $a; +\& ... +\& if (overload::Overloaded $b) {...} +\& ... +\& $strval = overload::StrVal $b; +.Ve +.SH DESCRIPTION +.IX Header "DESCRIPTION" +This pragma allows overloading of Perl's operators for a class. +To overload built-in functions, see "Overriding Built-in Functions" in perlsub instead. +.SS Fundamentals +.IX Subsection "Fundamentals" +\fIDeclaration\fR +.IX Subsection "Declaration" +.PP +Arguments of the \f(CW\*(C`use overload\*(C'\fR directive are (key, value) pairs. +For the full set of legal keys, see "Overloadable Operations" below. +.PP +Operator implementations (the values) can be subroutines, +references to subroutines, or anonymous subroutines +\&\- in other words, anything legal inside a \f(CW\*(C`&{ ... }\*(C'\fR call. +Values specified as strings are interpreted as method names. +Thus +.PP +.Vb 5 +\& package Number; +\& use overload +\& "\-" => "minus", +\& "*=" => \e&muas, +\& \*(Aq""\*(Aq => sub { ...; }; +.Ve +.PP +declares that subtraction is to be implemented by method \f(CWminus()\fR +in the class \f(CW\*(C`Number\*(C'\fR (or one of its base classes), +and that the function \f(CWNumber::muas()\fR is to be used for the +assignment form of multiplication, \f(CW\*(C`*=\*(C'\fR. +It also defines an anonymous subroutine to implement stringification: +this is called whenever an object blessed into the package \f(CW\*(C`Number\*(C'\fR +is used in a string context (this subroutine might, for example, +return the number as a Roman numeral). +.PP +\fICalling Conventions and Magic Autogeneration\fR +.IX Subsection "Calling Conventions and Magic Autogeneration" +.PP +The following sample implementation of \f(CWminus()\fR (which assumes +that \f(CW\*(C`Number\*(C'\fR objects are simply blessed references to scalars) +illustrates the calling conventions: +.PP +.Vb 8 +\& package Number; +\& sub minus { +\& my ($self, $other, $swap) = @_; +\& my $result = $$self \- $other; # * +\& $result = \-$result if $swap; +\& ref $result ? $result : bless \e$result; +\& } +\& # * may recurse once \- see table below +.Ve +.PP +Three arguments are passed to all subroutines specified in the +\&\f(CW\*(C`use overload\*(C'\fR directive (with exceptions \- see below, particularly +"nomethod"). +.PP +The first of these is the operand providing the overloaded +operator implementation \- +in this case, the object whose \f(CWminus()\fR method is being called. +.PP +The second argument is the other operand, or \f(CW\*(C`undef\*(C'\fR in the +case of a unary operator. +.PP +The third argument is set to TRUE if (and only if) the two +operands have been swapped. Perl may do this to ensure that the +first argument (\f(CW$self\fR) is an object implementing the overloaded +operation, in line with general object calling conventions. +For example, if \f(CW$x\fR and \f(CW$y\fR are \f(CW\*(C`Number\*(C'\fRs: +.PP +.Vb 5 +\& operation | generates a call to +\& ============|====================== +\& $x \- $y | minus($x, $y, \*(Aq\*(Aq) +\& $x \- 7 | minus($x, 7, \*(Aq\*(Aq) +\& 7 \- $x | minus($x, 7, 1) +.Ve +.PP +Perl may also use \f(CWminus()\fR to implement other operators which +have not been specified in the \f(CW\*(C`use overload\*(C'\fR directive, +according to the rules for "Magic Autogeneration" described later. +For example, the \f(CW\*(C`use overload\*(C'\fR above declared no subroutine +for any of the operators \f(CW\*(C`\-\-\*(C'\fR, \f(CW\*(C`neg\*(C'\fR (the overload key for +unary minus), or \f(CW\*(C`\-=\*(C'\fR. Thus +.PP +.Vb 5 +\& operation | generates a call to +\& ============|====================== +\& \-$x | minus($x, 0, 1) +\& $x\-\- | minus($x, 1, undef) +\& $x \-= 3 | minus($x, 3, undef) +.Ve +.PP +Note the \f(CW\*(C`undef\*(C'\fRs: +where autogeneration results in the method for a standard +operator which does not change either of its operands, such +as \f(CW\*(C`\-\*(C'\fR, being used to implement an operator which changes +the operand ("mutators": here, \f(CW\*(C`\-\-\*(C'\fR and \f(CW\*(C`\-=\*(C'\fR), +Perl passes undef as the third argument. +This still evaluates as FALSE, consistent with the fact that +the operands have not been swapped, but gives the subroutine +a chance to alter its behaviour in these cases. +.PP +In all the above examples, \f(CWminus()\fR is required +only to return the result of the subtraction: +Perl takes care of the assignment to \f(CW$x\fR. +In fact, such methods should \fInot\fR modify their operands, +even if \f(CW\*(C`undef\*(C'\fR is passed as the third argument +(see "Overloadable Operations"). +.PP +The same is not true of implementations of \f(CW\*(C`++\*(C'\fR and \f(CW\*(C`\-\-\*(C'\fR: +these are expected to modify their operand. +An appropriate implementation of \f(CW\*(C`\-\-\*(C'\fR might look like +.PP +.Vb 3 +\& use overload \*(Aq\-\-\*(Aq => "decr", +\& # ... +\& sub decr { \-\-${$_[0]}; } +.Ve +.PP +If the "bitwise" feature is enabled (see feature), a fifth +TRUE argument is passed to subroutines handling \f(CW\*(C`&\*(C'\fR, \f(CW\*(C`|\*(C'\fR, \f(CW\*(C`^\*(C'\fR and \f(CW\*(C`~\*(C'\fR. +This indicates that the caller is expecting numeric behaviour. The fourth +argument will be \f(CW\*(C`undef\*(C'\fR, as that position (\f(CW$_[3]\fR) is reserved for use +by "nomethod". +.PP +\fIMathemagic, Mutators, and Copy Constructors\fR +.IX Subsection "Mathemagic, Mutators, and Copy Constructors" +.PP +The term 'mathemagic' describes the overloaded implementation +of mathematical operators. +Mathemagical operations raise an issue. +Consider the code: +.PP +.Vb 2 +\& $a = $b; +\& \-\-$a; +.Ve +.PP +If \f(CW$a\fR and \f(CW$b\fR are scalars then after these statements +.PP +.Vb 1 +\& $a == $b \- 1 +.Ve +.PP +An object, however, is a reference to blessed data, so if +\&\f(CW$a\fR and \f(CW$b\fR are objects then the assignment \f(CW\*(C`$a = $b\*(C'\fR +copies only the reference, leaving \f(CW$a\fR and \f(CW$b\fR referring +to the same object data. +One might therefore expect the operation \f(CW\*(C`\-\-$a\*(C'\fR to decrement +\&\f(CW$b\fR as well as \f(CW$a\fR. +However, this would not be consistent with how we expect the +mathematical operators to work. +.PP +Perl resolves this dilemma by transparently calling a copy +constructor before calling a method defined to implement +a mutator (\f(CW\*(C`\-\-\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, and so on.). +In the above example, when Perl reaches the decrement +statement, it makes a copy of the object data in \f(CW$a\fR and +assigns to \f(CW$a\fR a reference to the copied data. +Only then does it call \f(CWdecr()\fR, which alters the copied +data, leaving \f(CW$b\fR unchanged. +Thus the object metaphor is preserved as far as possible, +while mathemagical operations still work according to the +arithmetic metaphor. +.PP +Note: the preceding paragraph describes what happens when +Perl autogenerates the copy constructor for an object based +on a scalar. +For other cases, see "Copy Constructor". +.SS "Overloadable Operations" +.IX Subsection "Overloadable Operations" +The complete list of keys that can be specified in the \f(CW\*(C`use overload\*(C'\fR +directive are given, separated by spaces, in the values of the +hash \f(CW%overload::ops\fR: +.PP +.Vb 10 +\& with_assign => \*(Aq+ \- * / % ** << >> x .\*(Aq, +\& assign => \*(Aq+= \-= *= /= %= **= <<= >>= x= .=\*(Aq, +\& num_comparison => \*(Aq< <= > >= == !=\*(Aq, +\& \*(Aq3way_comparison\*(Aq => \*(Aq<=> cmp\*(Aq, +\& str_comparison => \*(Aqlt le gt ge eq ne\*(Aq, +\& binary => \*(Aq& &= | |= ^ ^= &. &.= |. |.= ^. ^.=\*(Aq, +\& unary => \*(Aqneg ! ~ ~.\*(Aq, +\& mutators => \*(Aq++ \-\-\*(Aq, +\& func => \*(Aqatan2 cos sin exp abs log sqrt int\*(Aq, +\& conversion => \*(Aqbool "" 0+ qr\*(Aq, +\& iterators => \*(Aq<>\*(Aq, +\& filetest => \*(Aq\-X\*(Aq, +\& dereferencing => \*(Aq${} @{} %{} &{} *{}\*(Aq, +\& matching => \*(Aq~~\*(Aq, +\& special => \*(Aqnomethod fallback =\*(Aq, +.Ve +.PP +Most of the overloadable operators map one-to-one to these keys. +Exceptions, including additional overloadable operations not +apparent from this hash, are included in the notes which follow. +This list is subject to growth over time. +.PP +A warning is issued if an attempt is made to register an operator not found +above. +.IP \(bu 5 +\&\f(CW\*(C`not\*(C'\fR +.Sp +The operator \f(CW\*(C`not\*(C'\fR is not a valid key for \f(CW\*(C`use overload\*(C'\fR. +However, if the operator \f(CW\*(C`!\*(C'\fR is overloaded then the same +implementation will be used for \f(CW\*(C`not\*(C'\fR +(since the two operators differ only in precedence). +.IP \(bu 5 +\&\f(CW\*(C`neg\*(C'\fR +.Sp +The key \f(CW\*(C`neg\*(C'\fR is used for unary minus to disambiguate it from +binary \f(CW\*(C`\-\*(C'\fR. +.IP \(bu 5 +\&\f(CW\*(C`++\*(C'\fR, \f(CW\*(C`\-\-\*(C'\fR +.Sp +Assuming they are to behave analogously to Perl's \f(CW\*(C`++\*(C'\fR and \f(CW\*(C`\-\-\*(C'\fR, +overloaded implementations of these operators are required to +mutate their operands. +.Sp +No distinction is made between prefix and postfix forms of the +increment and decrement operators: these differ only in the +point at which Perl calls the associated subroutine when +evaluating an expression. +.IP \(bu 5 +\&\fIAssignments\fR +.Sp +.Vb 2 +\& += \-= *= /= %= **= <<= >>= x= .= +\& &= |= ^= &.= |.= ^.= +.Ve +.Sp +Simple assignment is not overloadable (the \f(CW\*(Aq=\*(Aq\fR key is used +for the "Copy Constructor"). +Perl does have a way to make assignments to an object do whatever +you want, but this involves using \fBtie()\fR, not overload \- +see "tie" in perlfunc and the "COOKBOOK" examples below. +.Sp +The subroutine for the assignment variant of an operator is +required only to return the result of the operation. +It is permitted to change the value of its operand +(this is safe because Perl calls the copy constructor first), +but this is optional since Perl assigns the returned value to +the left-hand operand anyway. +.Sp +An object that overloads an assignment operator does so only in +respect of assignments to that object. +In other words, Perl never calls the corresponding methods with +the third argument (the "swap" argument) set to TRUE. +For example, the operation +.Sp +.Vb 1 +\& $a *= $b +.Ve +.Sp +cannot lead to \f(CW$b\fR's implementation of \f(CW\*(C`*=\*(C'\fR being called, +even if \f(CW$a\fR is a scalar. +(It can, however, generate a call to \f(CW$b\fR's method for \f(CW\*(C`*\*(C'\fR). +.IP \(bu 5 +\&\fINon-mutators with a mutator variant\fR +.Sp +.Vb 2 +\& + \- * / % ** << >> x . +\& & | ^ &. |. ^. +.Ve +.Sp +As described above, +Perl may call methods for operators like \f(CW\*(C`+\*(C'\fR and \f(CW\*(C`&\*(C'\fR in the course +of implementing missing operations like \f(CW\*(C`++\*(C'\fR, \f(CW\*(C`+=\*(C'\fR, and \f(CW\*(C`&=\*(C'\fR. +While these methods may detect this usage by testing the definedness +of the third argument, they should in all cases avoid changing their +operands. +This is because Perl does not call the copy constructor before +invoking these methods. +.IP \(bu 5 +\&\f(CW\*(C`int\*(C'\fR +.Sp +Traditionally, the Perl function \f(CW\*(C`int\*(C'\fR rounds to 0 +(see "int" in perlfunc), and so for floating-point-like types one +should follow the same semantic. +.IP \(bu 5 +\&\fIString, numeric, boolean, and regexp conversions\fR +.Sp +.Vb 1 +\& "" 0+ bool +.Ve +.Sp +These conversions are invoked according to context as necessary. +For example, the subroutine for \f(CW\*(Aq""\*(Aq\fR (stringify) may be used +where the overloaded object is passed as an argument to \f(CW\*(C`print\*(C'\fR, +and that for \f(CW\*(Aqbool\*(Aq\fR where it is tested in the condition of a flow +control statement (like \f(CW\*(C`while\*(C'\fR) or the ternary \f(CW\*(C`?:\*(C'\fR operation. +.Sp +Of course, in contexts like, for example, \f(CW\*(C`$obj + 1\*(C'\fR, Perl will +invoke \f(CW$obj\fR's implementation of \f(CW\*(C`+\*(C'\fR rather than (in this +example) converting \f(CW$obj\fR to a number using the numify method +\&\f(CW\*(Aq0+\*(Aq\fR (an exception to this is when no method has been provided +for \f(CW\*(Aq+\*(Aq\fR and "fallback" is set to TRUE). +.Sp +The subroutines for \f(CW\*(Aq""\*(Aq\fR, \f(CW\*(Aq0+\*(Aq\fR, and \f(CW\*(Aqbool\*(Aq\fR can return +any arbitrary Perl value. +If the corresponding operation for this value is overloaded too, +the operation will be called again with this value. +.Sp +As a special case if the overload returns the object itself then it will +be used directly. An overloaded conversion returning the object is +probably a bug, because you're likely to get something that looks like +\&\f(CW\*(C`YourPackage=HASH(0x8172b34)\*(C'\fR. +.Sp +.Vb 1 +\& qr +.Ve +.Sp +The subroutine for \f(CW\*(Aqqr\*(Aq\fR is used wherever the object is +interpolated into or used as a regexp, including when it +appears on the RHS of a \f(CW\*(C`=~\*(C'\fR or \f(CW\*(C`!~\*(C'\fR operator. +.Sp +\&\f(CW\*(C`qr\*(C'\fR must return a compiled regexp, or a ref to a compiled regexp +(such as \f(CW\*(C`qr//\*(C'\fR returns), and any further overloading on the return +value will be ignored. +.IP \(bu 5 +\&\fIIteration\fR +.Sp +If \f(CW\*(C`<>\*(C'\fR is overloaded then the same implementation is used +for both the \fIread-filehandle\fR syntax \f(CW\*(C`<$var>\*(C'\fR and +\&\fIglobbing\fR syntax \f(CW\*(C`<${var}>\*(C'\fR. +.IP \(bu 5 +\&\fIFile tests\fR +.Sp +The key \f(CW\*(Aq\-X\*(Aq\fR is used to specify a subroutine to handle all the +filetest operators (\f(CW\*(C`\-f\*(C'\fR, \f(CW\*(C`\-x\*(C'\fR, and so on: see "\-X" in perlfunc for +the full list); +it is not possible to overload any filetest operator individually. +To distinguish them, the letter following the '\-' is passed as the +second argument (that is, in the slot that for binary operators +is used to pass the second operand). +.Sp +Calling an overloaded filetest operator does not affect the stat value +associated with the special filehandle \f(CW\*(C`_\*(C'\fR. It still refers to the +result of the last \f(CW\*(C`stat\*(C'\fR, \f(CW\*(C`lstat\*(C'\fR or unoverloaded filetest. +.Sp +This overload was introduced in Perl 5.12. +.IP \(bu 5 +\&\fIMatching\fR +.Sp +The key \f(CW"~~"\fR allows you to override the smart matching logic used by +the \f(CW\*(C`~~\*(C'\fR operator and the switch construct (\f(CW\*(C`given\*(C'\fR/\f(CW\*(C`when\*(C'\fR). See +"Switch Statements" in perlsyn and feature. +.Sp +Unusually, the overloaded implementation of the smart match operator +does not get full control of the smart match behaviour. +In particular, in the following code: +.Sp +.Vb 2 +\& package Foo; +\& use overload \*(Aq~~\*(Aq => \*(Aqmatch\*(Aq; +\& +\& my $obj = Foo\->new(); +\& $obj ~~ [ 1,2,3 ]; +.Ve +.Sp +the smart match does \fInot\fR invoke the method call like this: +.Sp +.Vb 1 +\& $obj\->match([1,2,3],0); +.Ve +.Sp +rather, the smart match distributive rule takes precedence, so \f(CW$obj\fR is +smart matched against each array element in turn until a match is found, +so you may see between one and three of these calls instead: +.Sp +.Vb 3 +\& $obj\->match(1,0); +\& $obj\->match(2,0); +\& $obj\->match(3,0); +.Ve +.Sp +Consult the match table in "Smartmatch Operator" in perlop for +details of when overloading is invoked. +.IP \(bu 5 +\&\fIDereferencing\fR +.Sp +.Vb 1 +\& ${} @{} %{} &{} *{} +.Ve +.Sp +If these operators are not explicitly overloaded then they +work in the normal way, yielding the underlying scalar, +array, or whatever stores the object data (or the appropriate +error message if the dereference operator doesn't match it). +Defining a catch-all \f(CW\*(Aqnomethod\*(Aq\fR (see below) +makes no difference to this as the catch-all function will +not be called to implement a missing dereference operator. +.Sp +If a dereference operator is overloaded then it must return a +\&\fIreference\fR of the appropriate type (for example, the +subroutine for key \f(CW\*(Aq${}\*(Aq\fR should return a reference to a +scalar, not a scalar), or another object which overloads the +operator: that is, the subroutine only determines what is +dereferenced and the actual dereferencing is left to Perl. +As a special case, if the subroutine returns the object itself +then it will not be called again \- avoiding infinite recursion. +.IP \(bu 5 +\&\fISpecial\fR +.Sp +.Vb 1 +\& nomethod fallback = +.Ve +.Sp +See "Special Keys for \f(CW\*(C`use overload\*(C'\fR". +.SS "Magic Autogeneration" +.IX Subsection "Magic Autogeneration" +If a method for an operation is not found then Perl tries to +autogenerate a substitute implementation from the operations +that have been defined. +.PP +Note: the behaviour described in this section can be disabled +by setting \f(CW\*(C`fallback\*(C'\fR to FALSE (see "fallback"). +.PP +In the following tables, numbers indicate priority. +For example, the table below states that, +if no implementation for \f(CW\*(Aq!\*(Aq\fR has been defined then Perl will +implement it using \f(CW\*(Aqbool\*(Aq\fR (that is, by inverting the value +returned by the method for \f(CW\*(Aqbool\*(Aq\fR); +if boolean conversion is also unimplemented then Perl will +use \f(CW\*(Aq0+\*(Aq\fR or, failing that, \f(CW\*(Aq""\*(Aq\fR. +.PP +.Vb 10 +\& operator | can be autogenerated from +\& | +\& | 0+ "" bool . x +\& =========|========================== +\& 0+ | 1 2 +\& "" | 1 2 +\& bool | 1 2 +\& int | 1 2 3 +\& ! | 2 3 1 +\& qr | 2 1 3 +\& . | 2 1 3 +\& x | 2 1 3 +\& .= | 3 2 4 1 +\& x= | 3 2 4 1 +\& <> | 2 1 3 +\& \-X | 2 1 3 +.Ve +.PP +Note: The iterator (\f(CW\*(Aq<>\*(Aq\fR) and file test (\f(CW\*(Aq\-X\*(Aq\fR) +operators work as normal: if the operand is not a blessed glob or +IO reference then it is converted to a string (using the method +for \f(CW\*(Aq""\*(Aq\fR, \f(CW\*(Aq0+\*(Aq\fR, or \f(CW\*(Aqbool\*(Aq\fR) to be interpreted as a glob +or filename. +.PP +.Vb 10 +\& operator | can be autogenerated from +\& | +\& | < <=> neg \-= \- +\& =========|========================== +\& neg | 1 +\& \-= | 1 +\& \-\- | 1 2 +\& abs | a1 a2 b1 b2 [*] +\& < | 1 +\& <= | 1 +\& > | 1 +\& >= | 1 +\& == | 1 +\& != | 1 +\& +\& * one from [a1, a2] and one from [b1, b2] +.Ve +.PP +Just as numeric comparisons can be autogenerated from the method +for \f(CW\*(Aq<=>\*(Aq\fR, string comparisons can be autogenerated from +that for \f(CW\*(Aqcmp\*(Aq\fR: +.PP +.Vb 3 +\& operators | can be autogenerated from +\& ====================|=========================== +\& lt gt le ge eq ne | cmp +.Ve +.PP +Similarly, autogeneration for keys \f(CW\*(Aq+=\*(Aq\fR and \f(CW\*(Aq++\*(Aq\fR is analogous +to \f(CW\*(Aq\-=\*(Aq\fR and \f(CW\*(Aq\-\-\*(Aq\fR above: +.PP +.Vb 6 +\& operator | can be autogenerated from +\& | +\& | += + +\& =========|========================== +\& += | 1 +\& ++ | 1 2 +.Ve +.PP +And other assignment variations are analogous to +\&\f(CW\*(Aq+=\*(Aq\fR and \f(CW\*(Aq\-=\*(Aq\fR (and similar to \f(CW\*(Aq.=\*(Aq\fR and \f(CW\*(Aqx=\*(Aq\fR above): +.PP +.Vb 3 +\& operator || *= /= %= **= <<= >>= &= ^= |= &.= ^.= |.= +\& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-||\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- +\& autogenerated from || * / % ** << >> & ^ | &. ^. |. +.Ve +.PP +Note also that the copy constructor (key \f(CW\*(Aq=\*(Aq\fR) may be +autogenerated, but only for objects based on scalars. +See "Copy Constructor". +.PP +\fIMinimal Set of Overloaded Operations\fR +.IX Subsection "Minimal Set of Overloaded Operations" +.PP +Since some operations can be automatically generated from others, there is +a minimal set of operations that need to be overloaded in order to have +the complete set of overloaded operations at one's disposal. +Of course, the autogenerated operations may not do exactly what the user +expects. The minimal set is: +.PP +.Vb 6 +\& + \- * / % ** << >> x +\& <=> cmp +\& & | ^ ~ &. |. ^. ~. +\& atan2 cos sin exp log sqrt int +\& "" 0+ bool +\& ~~ +.Ve +.PP +Of the conversions, only one of string, boolean or numeric is +needed because each can be generated from either of the other two. +.ie n .SS "Special Keys for ""use overload""" +.el .SS "Special Keys for \f(CWuse overload\fP" +.IX Subsection "Special Keys for use overload" +\fR\f(CI\*(C`nomethod\*(C'\fR\fI\fR +.IX Subsection "nomethod" +.PP +The \f(CW\*(Aqnomethod\*(Aq\fR key is used to specify a catch-all function to +be called for any operator that is not individually overloaded. +The specified function will be passed four parameters. +The first three arguments coincide with those that would have been +passed to the corresponding method if it had been defined. +The fourth argument is the \f(CW\*(C`use overload\*(C'\fR key for that missing +method. If the "bitwise" feature is enabled (see feature), +a fifth TRUE argument is passed to subroutines handling \f(CW\*(C`&\*(C'\fR, \f(CW\*(C`|\*(C'\fR, \f(CW\*(C`^\*(C'\fR and \f(CW\*(C`~\*(C'\fR to indicate that the caller is expecting numeric behaviour. +.PP +For example, if \f(CW$a\fR is an object blessed into a package declaring +.PP +.Vb 1 +\& use overload \*(Aqnomethod\*(Aq => \*(Aqcatch_all\*(Aq, # ... +.Ve +.PP +then the operation +.PP +.Vb 1 +\& 3 + $a +.Ve +.PP +could (unless a method is specifically declared for the key +\&\f(CW\*(Aq+\*(Aq\fR) result in a call +.PP +.Vb 1 +\& catch_all($a, 3, 1, \*(Aq+\*(Aq) +.Ve +.PP +See "How Perl Chooses an Operator Implementation". +.PP +\fR\f(CI\*(C`fallback\*(C'\fR\fI\fR +.IX Subsection "fallback" +.PP +The value assigned to the key \f(CW\*(Aqfallback\*(Aq\fR tells Perl how hard +it should try to find an alternative way to implement a missing +operator. +.IP \(bu 4 +defined, but FALSE +.Sp +.Vb 1 +\& use overload "fallback" => 0, # ... ; +.Ve +.Sp +This disables "Magic Autogeneration". +.IP \(bu 4 +\&\f(CW\*(C`undef\*(C'\fR +.Sp +In the default case where no value is explicitly assigned to +\&\f(CW\*(C`fallback\*(C'\fR, magic autogeneration is enabled. +.IP \(bu 4 +TRUE +.Sp +The same as for \f(CW\*(C`undef\*(C'\fR, but if a missing operator cannot be +autogenerated then, instead of issuing an error message, Perl +is allowed to revert to what it would have done for that +operator if there had been no \f(CW\*(C`use overload\*(C'\fR directive. +.Sp +Note: in most cases, particularly the "Copy Constructor", +this is unlikely to be appropriate behaviour. +.PP +See "How Perl Chooses an Operator Implementation". +.PP +\fICopy Constructor\fR +.IX Subsection "Copy Constructor" +.PP +As mentioned above, +this operation is called when a mutator is applied to a reference +that shares its object with some other reference. +For example, if \f(CW$b\fR is mathemagical, and \f(CW\*(Aq++\*(Aq\fR is overloaded +with \f(CW\*(Aqincr\*(Aq\fR, and \f(CW\*(Aq=\*(Aq\fR is overloaded with \f(CW\*(Aqclone\*(Aq\fR, then the +code +.PP +.Vb 3 +\& $a = $b; +\& # ... (other code which does not modify $a or $b) ... +\& ++$b; +.Ve +.PP +would be executed in a manner equivalent to +.PP +.Vb 4 +\& $a = $b; +\& # ... +\& $b = $b\->clone(undef, ""); +\& $b\->incr(undef, ""); +.Ve +.PP +Note: +.IP \(bu 4 +The subroutine for \f(CW\*(Aq=\*(Aq\fR does not overload the Perl assignment +operator: it is used only to allow mutators to work as described +here. (See "Assignments" above.) +.IP \(bu 4 +As for other operations, the subroutine implementing '=' is passed +three arguments, though the last two are always \f(CW\*(C`undef\*(C'\fR and \f(CW\*(Aq\*(Aq\fR. +.IP \(bu 4 +The copy constructor is called only before a call to a function +declared to implement a mutator, for example, if \f(CW\*(C`++$b;\*(C'\fR in the +code above is effected via a method declared for key \f(CW\*(Aq++\*(Aq\fR +(or 'nomethod', passed \f(CW\*(Aq++\*(Aq\fR as the fourth argument) or, by +autogeneration, \f(CW\*(Aq+=\*(Aq\fR. +It is not called if the increment operation is effected by a call +to the method for \f(CW\*(Aq+\*(Aq\fR since, in the equivalent code, +.Sp +.Vb 2 +\& $a = $b; +\& $b = $b + 1; +.Ve +.Sp +the data referred to by \f(CW$a\fR is unchanged by the assignment to +\&\f(CW$b\fR of a reference to new object data. +.IP \(bu 4 +The copy constructor is not called if Perl determines that it is +unnecessary because there is no other reference to the data being +modified. +.IP \(bu 4 +If \f(CW\*(Aqfallback\*(Aq\fR is undefined or TRUE then a copy constructor +can be autogenerated, but only for objects based on scalars. +In other cases it needs to be defined explicitly. +Where an object's data is stored as, for example, an array of +scalars, the following might be appropriate: +.Sp +.Vb 1 +\& use overload \*(Aq=\*(Aq => sub { bless [ @{$_[0]} ] }, # ... +.Ve +.IP \(bu 4 +If \f(CW\*(Aqfallback\*(Aq\fR is TRUE and no copy constructor is defined then, +for objects not based on scalars, Perl may silently fall back on +simple assignment \- that is, assignment of the object reference. +In effect, this disables the copy constructor mechanism since +no new copy of the object data is created. +This is almost certainly not what you want. +(It is, however, consistent: for example, Perl's fallback for the +\&\f(CW\*(C`++\*(C'\fR operator is to increment the reference itself.) +.SS "How Perl Chooses an Operator Implementation" +.IX Subsection "How Perl Chooses an Operator Implementation" +Which is checked first, \f(CW\*(C`nomethod\*(C'\fR or \f(CW\*(C`fallback\*(C'\fR? +If the two operands of an operator are of different types and +both overload the operator, which implementation is used? +The following are the precedence rules: +.IP 1. 4 +If the first operand has declared a subroutine to overload the +operator then use that implementation. +.IP 2. 4 +Otherwise, if fallback is TRUE or undefined for the +first operand then see if the +rules for autogeneration +allows another of its operators to be used instead. +.IP 3. 4 +Unless the operator is an assignment (\f(CW\*(C`+=\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR, etc.), +repeat step (1) in respect of the second operand. +.IP 4. 4 +Repeat Step (2) in respect of the second operand. +.IP 5. 4 +If the first operand has a "nomethod" method then use that. +.IP 6. 4 +If the second operand has a "nomethod" method then use that. +.IP 7. 4 +If \f(CW\*(C`fallback\*(C'\fR is TRUE for both operands +then perform the usual operation for the operator, +treating the operands as numbers, strings, or booleans +as appropriate for the operator (see note). +.IP 8. 4 +Nothing worked \- die. +.PP +Where there is only one operand (or only one operand with +overloading) the checks in respect of the other operand above are +skipped. +.PP +There are exceptions to the above rules for dereference operations +(which, if Step 1 fails, always fall back to the normal, built-in +implementations \- see Dereferencing), and for \f(CW\*(C`~~\*(C'\fR (which has its +own set of rules \- see \f(CW\*(C`Matching\*(C'\fR under "Overloadable Operations" +above). +.PP +Note on Step 7: some operators have a different semantic depending +on the type of their operands. +As there is no way to instruct Perl to treat the operands as, e.g., +numbers instead of strings, the result here may not be what you +expect. +See "BUGS AND PITFALLS". +.SS "Losing Overloading" +.IX Subsection "Losing Overloading" +The restriction for the comparison operation is that even if, for example, +\&\f(CW\*(C`cmp\*(C'\fR should return a blessed reference, the autogenerated \f(CW\*(C`lt\*(C'\fR +function will produce only a standard logical value based on the +numerical value of the result of \f(CW\*(C`cmp\*(C'\fR. In particular, a working +numeric conversion is needed in this case (possibly expressed in terms of +other conversions). +.PP +Similarly, \f(CW\*(C`.=\*(C'\fR and \f(CW\*(C`x=\*(C'\fR operators lose their mathemagical properties +if the string conversion substitution is applied. +.PP +When you \fBchop()\fR a mathemagical object it is promoted to a string and its +mathemagical properties are lost. The same can happen with other +operations as well. +.SS "Inheritance and Overloading" +.IX Subsection "Inheritance and Overloading" +Overloading respects inheritance via the \f(CW@ISA\fR hierarchy. +Inheritance interacts with overloading in two ways. +.ie n .IP "Method names in the ""use overload"" directive" 4 +.el .IP "Method names in the \f(CWuse overload\fR directive" 4 +.IX Item "Method names in the use overload directive" +If \f(CW\*(C`value\*(C'\fR in +.Sp +.Vb 1 +\& use overload key => value; +.Ve +.Sp +is a string, it is interpreted as a method name \- which may +(in the usual way) be inherited from another class. +.IP "Overloading of an operation is inherited by derived classes" 4 +.IX Item "Overloading of an operation is inherited by derived classes" +Any class derived from an overloaded class is also overloaded +and inherits its operator implementations. +If the same operator is overloaded in more than one ancestor +then the implementation is determined by the usual inheritance +rules. +.Sp +For example, if \f(CW\*(C`A\*(C'\fR inherits from \f(CW\*(C`B\*(C'\fR and \f(CW\*(C`C\*(C'\fR (in that order), +\&\f(CW\*(C`B\*(C'\fR overloads \f(CW\*(C`+\*(C'\fR with \f(CW\*(C`\e&D::plus_sub\*(C'\fR, and \f(CW\*(C`C\*(C'\fR overloads +\&\f(CW\*(C`+\*(C'\fR by \f(CW"plus_meth"\fR, then the subroutine \f(CW\*(C`D::plus_sub\*(C'\fR will +be called to implement operation \f(CW\*(C`+\*(C'\fR for an object in package \f(CW\*(C`A\*(C'\fR. +.PP +Note that in Perl version prior to 5.18 inheritance of the \f(CW\*(C`fallback\*(C'\fR key +was not governed by the above rules. The value of \f(CW\*(C`fallback\*(C'\fR in the first +overloaded ancestor was used. This was fixed in 5.18 to follow the usual +rules of inheritance. +.SS "Run-time Overloading" +.IX Subsection "Run-time Overloading" +Since all \f(CW\*(C`use\*(C'\fR directives are executed at compile-time, the only way to +change overloading during run-time is to +.PP +.Vb 1 +\& eval \*(Aquse overload "+" => \e&addmethod\*(Aq; +.Ve +.PP +You can also use +.PP +.Vb 1 +\& eval \*(Aqno overload "+", "\-\-", "<="\*(Aq; +.Ve +.PP +though the use of these constructs during run-time is questionable. +.SS "Public Functions" +.IX Subsection "Public Functions" +Package \f(CW\*(C`overload.pm\*(C'\fR provides the following public functions: +.IP overload::StrVal(arg) 5 +.IX Item "overload::StrVal(arg)" +Gives the string value of \f(CW\*(C`arg\*(C'\fR as in the +absence of stringify overloading. If you +are using this to get the address of a reference (useful for checking if two +references point to the same thing) then you may be better off using +\&\f(CWbuiltin::refaddr()\fR or \f(CWScalar::Util::refaddr()\fR, which are faster. +.IP overload::Overloaded(arg) 5 +.IX Item "overload::Overloaded(arg)" +Returns true if \f(CW\*(C`arg\*(C'\fR is subject to overloading of some operations. +.IP overload::Method(obj,op) 5 +.IX Item "overload::Method(obj,op)" +Returns \f(CW\*(C`undef\*(C'\fR or a reference to the method that implements \f(CW\*(C`op\*(C'\fR. +.Sp +Such a method always takes three arguments, which will be enforced if +it is an XS method. +.SS "Overloading Constants" +.IX Subsection "Overloading Constants" +For some applications, the Perl parser mangles constants too much. +It is possible to hook into this process via \f(CWoverload::constant()\fR +and \f(CWoverload::remove_constant()\fR functions. +.PP +These functions take a hash as an argument. The recognized keys of this hash +are: +.IP integer 8 +.IX Item "integer" +to overload integer constants, +.IP float 8 +.IX Item "float" +to overload floating point constants, +.IP binary 8 +.IX Item "binary" +to overload octal and hexadecimal constants, +.IP q 8 +.IX Item "q" +to overload \f(CW\*(C`q\*(C'\fR\-quoted strings, constant pieces of \f(CW\*(C`qq\*(C'\fR\- and \f(CW\*(C`qx\*(C'\fR\-quoted +strings and here-documents, +.IP qr 8 +.IX Item "qr" +to overload constant pieces of regular expressions. +.PP +The corresponding values are references to functions which take three arguments: +the first one is the \fIinitial\fR string form of the constant, the second one +is how Perl interprets this constant, the third one is how the constant is used. +Note that the initial string form does not +contain string delimiters, and has backslashes in backslash-delimiter +combinations stripped (thus the value of delimiter is not relevant for +processing of this string). The return value of this function is how this +constant is going to be interpreted by Perl. The third argument is undefined +unless for overloaded \f(CW\*(C`q\*(C'\fR\- and \f(CW\*(C`qr\*(C'\fR\- constants, it is \f(CW\*(C`q\*(C'\fR in single-quote +context (comes from strings, regular expressions, and single-quote HERE +documents), it is \f(CW\*(C`tr\*(C'\fR for arguments of \f(CW\*(C`tr\*(C'\fR/\f(CW\*(C`y\*(C'\fR operators, +it is \f(CW\*(C`s\*(C'\fR for right-hand side of \f(CW\*(C`s\*(C'\fR\-operator, and it is \f(CW\*(C`qq\*(C'\fR otherwise. +.PP +Since an expression \f(CW"ab$cd,,"\fR is just a shortcut for \f(CW\*(Aqab\*(Aq . $cd . \*(Aq,,\*(Aq\fR, +it is expected that overloaded constant strings are equipped with reasonable +overloaded catenation operator, otherwise absurd results will result. +Similarly, negative numbers are considered as negations of positive constants. +.PP +Note that it is probably meaningless to call the functions \fBoverload::constant()\fR +and \fBoverload::remove_constant()\fR from anywhere but \fBimport()\fR and \fBunimport()\fR methods. +From these methods they may be called as +.PP +.Vb 6 +\& sub import { +\& shift; +\& return unless @_; +\& die "unknown import: @_" unless @_ == 1 and $_[0] eq \*(Aq:constant\*(Aq; +\& overload::constant integer => sub {Math::BigInt\->new(shift)}; +\& } +.Ve +.SH IMPLEMENTATION +.IX Header "IMPLEMENTATION" +What follows is subject to change RSN. +.PP +The table of methods for all operations is cached in magic for the +symbol table hash for the package. The cache is invalidated during +processing of \f(CW\*(C`use overload\*(C'\fR, \f(CW\*(C`no overload\*(C'\fR, new function +definitions, and changes in \f(CW@ISA\fR. +.PP +(Every SVish thing has a magic queue, and magic is an entry in that +queue. This is how a single variable may participate in multiple +forms of magic simultaneously. For instance, environment variables +regularly have two forms at once: their \f(CW%ENV\fR magic and their taint +magic. However, the magic which implements overloading is applied to +the stashes, which are rarely used directly, thus should not slow down +Perl.) +.PP +If a package uses overload, it carries a special flag. This flag is also +set when new functions are defined or \f(CW@ISA\fR is modified. There will be a +slight speed penalty on the very first operation thereafter that supports +overloading, while the overload tables are updated. If there is no +overloading present, the flag is turned off. Thus the only speed penalty +thereafter is the checking of this flag. +.PP +It is expected that arguments to methods that are not explicitly supposed +to be changed are constant (but this is not enforced). +.SH COOKBOOK +.IX Header "COOKBOOK" +Please add examples to what follows! +.SS "Two-face Scalars" +.IX Subsection "Two-face Scalars" +Put this in \fItwo_face.pm\fR in your Perl library directory: +.PP +.Vb 6 +\& package two_face; # Scalars with separate string and +\& # numeric values. +\& sub new { my $p = shift; bless [@_], $p } +\& use overload \*(Aq""\*(Aq => \e&str, \*(Aq0+\*(Aq => \e&num, fallback => 1; +\& sub num {shift\->[1]} +\& sub str {shift\->[0]} +.Ve +.PP +Use it as follows: +.PP +.Vb 4 +\& require two_face; +\& my $seven = two_face\->new("vii", 7); +\& printf "seven=$seven, seven=%d, eight=%d\en", $seven, $seven+1; +\& print "seven contains \*(Aqi\*(Aq\en" if $seven =~ /i/; +.Ve +.PP +(The second line creates a scalar which has both a string value, and a +numeric value.) This prints: +.PP +.Vb 2 +\& seven=vii, seven=7, eight=8 +\& seven contains \*(Aqi\*(Aq +.Ve +.SS "Two-face References" +.IX Subsection "Two-face References" +Suppose you want to create an object which is accessible as both an +array reference and a hash reference. +.PP +.Vb 12 +\& package two_refs; +\& use overload \*(Aq%{}\*(Aq => \e&gethash, \*(Aq@{}\*(Aq => sub { $ {shift()} }; +\& sub new { +\& my $p = shift; +\& bless \e [@_], $p; +\& } +\& sub gethash { +\& my %h; +\& my $self = shift; +\& tie %h, ref $self, $self; +\& \e%h; +\& } +\& +\& sub TIEHASH { my $p = shift; bless \e shift, $p } +\& my %fields; +\& my $i = 0; +\& $fields{$_} = $i++ foreach qw{zero one two three}; +\& sub STORE { +\& my $self = ${shift()}; +\& my $key = $fields{shift()}; +\& defined $key or die "Out of band access"; +\& $$self\->[$key] = shift; +\& } +\& sub FETCH { +\& my $self = ${shift()}; +\& my $key = $fields{shift()}; +\& defined $key or die "Out of band access"; +\& $$self\->[$key]; +\& } +.Ve +.PP +Now one can access an object using both the array and hash syntax: +.PP +.Vb 3 +\& my $bar = two_refs\->new(3,4,5,6); +\& $bar\->[2] = 11; +\& $bar\->{two} == 11 or die \*(Aqbad hash fetch\*(Aq; +.Ve +.PP +Note several important features of this example. First of all, the +\&\fIactual\fR type of \f(CW$bar\fR is a scalar reference, and we do not overload +the scalar dereference. Thus we can get the \fIactual\fR non-overloaded +contents of \f(CW$bar\fR by just using \f(CW$$bar\fR (what we do in functions which +overload dereference). Similarly, the object returned by the +\&\fBTIEHASH()\fR method is a scalar reference. +.PP +Second, we create a new tied hash each time the hash syntax is used. +This allows us not to worry about a possibility of a reference loop, +which would lead to a memory leak. +.PP +Both these problems can be cured. Say, if we want to overload hash +dereference on a reference to an object which is \fIimplemented\fR as a +hash itself, the only problem one has to circumvent is how to access +this \fIactual\fR hash (as opposed to the \fIvirtual\fR hash exhibited by the +overloaded dereference operator). Here is one possible fetching routine: +.PP +.Vb 8 +\& sub access_hash { +\& my ($self, $key) = (shift, shift); +\& my $class = ref $self; +\& bless $self, \*(Aqoverload::dummy\*(Aq; # Disable overloading of %{} +\& my $out = $self\->{$key}; +\& bless $self, $class; # Restore overloading +\& $out; +\& } +.Ve +.PP +To remove creation of the tied hash on each access, one may an extra +level of indirection which allows a non-circular structure of references: +.PP +.Vb 4 +\& package two_refs1; +\& use overload +\& \*(Aq%{}\*(Aq => sub { ${shift()}\->[1] }, +\& \*(Aq@{}\*(Aq => sub { ${shift()}\->[0] }; +\& +\& sub new { +\& my $p = shift; +\& my $a = [@_]; +\& my %h; +\& tie %h, $p, $a; +\& bless \e [$a, \e%h], $p; +\& } +\& sub gethash { +\& my %h; +\& my $self = shift; +\& tie %h, ref $self, $self; +\& \e%h; +\& } +\& +\& sub TIEHASH { my $p = shift; bless \e shift, $p } +\& my %fields; +\& my $i = 0; +\& $fields{$_} = $i++ foreach qw{zero one two three}; +\& sub STORE { +\& my $a = ${shift()}; +\& my $key = $fields{shift()}; +\& defined $key or die "Out of band access"; +\& $a\->[$key] = shift; +\& } +\& sub FETCH { +\& my $a = ${shift()}; +\& my $key = $fields{shift()}; +\& defined $key or die "Out of band access"; +\& $a\->[$key]; +\& } +.Ve +.PP +Now if \f(CW$baz\fR is overloaded like this, then \f(CW$baz\fR is a reference to a +reference to the intermediate array, which keeps a reference to an +actual array, and the access hash. The \fBtie()\fRing object for the access +hash is a reference to a reference to the actual array, so +.IP \(bu 4 +There are no loops of references. +.IP \(bu 4 +Both "objects" which are blessed into the class \f(CW\*(C`two_refs1\*(C'\fR are +references to a reference to an array, thus references to a \fIscalar\fR. +Thus the accessor expression \f(CW\*(C`$$foo\->[$ind]\*(C'\fR involves no +overloaded operations. +.SS "Symbolic Calculator" +.IX Subsection "Symbolic Calculator" +Put this in \fIsymbolic.pm\fR in your Perl library directory: +.PP +.Vb 2 +\& package symbolic; # Primitive symbolic calculator +\& use overload nomethod => \e&wrap; +\& +\& sub new { shift; bless [\*(Aqn\*(Aq, @_] } +\& sub wrap { +\& my ($obj, $other, $inv, $meth) = @_; +\& ($obj, $other) = ($other, $obj) if $inv; +\& bless [$meth, $obj, $other]; +\& } +.Ve +.PP +This module is very unusual as overloaded modules go: it does not +provide any usual overloaded operators, instead it provides an +implementation for \f(CW"nomethod"\fR. In this example the \f(CW\*(C`nomethod\*(C'\fR +subroutine returns an object which encapsulates operations done over +the objects: \f(CW\*(C`symbolic\->new(3)\*(C'\fR contains \f(CW\*(C`[\*(Aqn\*(Aq, 3]\*(C'\fR, \f(CW\*(C`2 + +symbolic\->new(3)\*(C'\fR contains \f(CW\*(C`[\*(Aq+\*(Aq, 2, [\*(Aqn\*(Aq, 3]]\*(C'\fR. +.PP +Here is an example of the script which "calculates" the side of +circumscribed octagon using the above package: +.PP +.Vb 4 +\& require symbolic; +\& my $iter = 1; # 2**($iter+2) = 8 +\& my $side = symbolic\->new(1); +\& my $cnt = $iter; +\& +\& while ($cnt\-\-) { +\& $side = (sqrt(1 + $side**2) \- 1)/$side; +\& } +\& print "OK\en"; +.Ve +.PP +The value of \f(CW$side\fR is +.PP +.Vb 2 +\& [\*(Aq/\*(Aq, [\*(Aq\-\*(Aq, [\*(Aqsqrt\*(Aq, [\*(Aq+\*(Aq, 1, [\*(Aq**\*(Aq, [\*(Aqn\*(Aq, 1], 2]], +\& undef], 1], [\*(Aqn\*(Aq, 1]] +.Ve +.PP +Note that while we obtained this value using a nice little script, +there is no simple way to \fIuse\fR this value. In fact this value may +be inspected in debugger (see perldebug), but only if +\&\f(CW\*(C`bareStringify\*(C'\fR \fBO\fRption is set, and not via \f(CW\*(C`p\*(C'\fR command. +.PP +If one attempts to print this value, then the overloaded operator +\&\f(CW""\fR will be called, which will call \f(CW\*(C`nomethod\*(C'\fR operator. The +result of this operator will be stringified again, but this result is +again of type \f(CW\*(C`symbolic\*(C'\fR, which will lead to an infinite loop. +.PP +Add a pretty-printer method to the module \fIsymbolic.pm\fR: +.PP +.Vb 8 +\& sub pretty { +\& my ($meth, $a, $b) = @{+shift}; +\& $a = \*(Aqu\*(Aq unless defined $a; +\& $b = \*(Aqu\*(Aq unless defined $b; +\& $a = $a\->pretty if ref $a; +\& $b = $b\->pretty if ref $b; +\& "[$meth $a $b]"; +\& } +.Ve +.PP +Now one can finish the script by +.PP +.Vb 1 +\& print "side = ", $side\->pretty, "\en"; +.Ve +.PP +The method \f(CW\*(C`pretty\*(C'\fR is doing object-to-string conversion, so it +is natural to overload the operator \f(CW""\fR using this method. However, +inside such a method it is not necessary to pretty-print the +\&\fIcomponents\fR \f(CW$a\fR and \f(CW$b\fR of an object. In the above subroutine +\&\f(CW"[$meth $a $b]"\fR is a catenation of some strings and components \f(CW$a\fR +and \f(CW$b\fR. If these components use overloading, the catenation operator +will look for an overloaded operator \f(CW\*(C`.\*(C'\fR; if not present, it will +look for an overloaded operator \f(CW""\fR. Thus it is enough to use +.PP +.Vb 7 +\& use overload nomethod => \e&wrap, \*(Aq""\*(Aq => \e&str; +\& sub str { +\& my ($meth, $a, $b) = @{+shift}; +\& $a = \*(Aqu\*(Aq unless defined $a; +\& $b = \*(Aqu\*(Aq unless defined $b; +\& "[$meth $a $b]"; +\& } +.Ve +.PP +Now one can change the last line of the script to +.PP +.Vb 1 +\& print "side = $side\en"; +.Ve +.PP +which outputs +.PP +.Vb 1 +\& side = [/ [\- [sqrt [+ 1 [** [n 1 u] 2]] u] 1] [n 1 u]] +.Ve +.PP +and one can inspect the value in debugger using all the possible +methods. +.PP +Something is still amiss: consider the loop variable \f(CW$cnt\fR of the +script. It was a number, not an object. We cannot make this value of +type \f(CW\*(C`symbolic\*(C'\fR, since then the loop will not terminate. +.PP +Indeed, to terminate the cycle, the \f(CW$cnt\fR should become false. +However, the operator \f(CW\*(C`bool\*(C'\fR for checking falsity is overloaded (this +time via overloaded \f(CW""\fR), and returns a long string, thus any object +of type \f(CW\*(C`symbolic\*(C'\fR is true. To overcome this, we need a way to +compare an object to 0. In fact, it is easier to write a numeric +conversion routine. +.PP +Here is the text of \fIsymbolic.pm\fR with such a routine added (and +slightly modified \fBstr()\fR): +.PP +.Vb 3 +\& package symbolic; # Primitive symbolic calculator +\& use overload +\& nomethod => \e&wrap, \*(Aq""\*(Aq => \e&str, \*(Aq0+\*(Aq => \e# +\& +\& sub new { shift; bless [\*(Aqn\*(Aq, @_] } +\& sub wrap { +\& my ($obj, $other, $inv, $meth) = @_; +\& ($obj, $other) = ($other, $obj) if $inv; +\& bless [$meth, $obj, $other]; +\& } +\& sub str { +\& my ($meth, $a, $b) = @{+shift}; +\& $a = \*(Aqu\*(Aq unless defined $a; +\& if (defined $b) { +\& "[$meth $a $b]"; +\& } else { +\& "[$meth $a]"; +\& } +\& } +\& my %subr = ( +\& n => sub {$_[0]}, +\& sqrt => sub {sqrt $_[0]}, +\& \*(Aq\-\*(Aq => sub {shift() \- shift()}, +\& \*(Aq+\*(Aq => sub {shift() + shift()}, +\& \*(Aq/\*(Aq => sub {shift() / shift()}, +\& \*(Aq*\*(Aq => sub {shift() * shift()}, +\& \*(Aq**\*(Aq => sub {shift() ** shift()}, +\& ); +\& sub num { +\& my ($meth, $a, $b) = @{+shift}; +\& my $subr = $subr{$meth} +\& or die "Do not know how to ($meth) in symbolic"; +\& $a = $a\->num if ref $a eq _\|_PACKAGE_\|_; +\& $b = $b\->num if ref $b eq _\|_PACKAGE_\|_; +\& $subr\->($a,$b); +\& } +.Ve +.PP +All the work of numeric conversion is done in \f(CW%subr\fR and \fBnum()\fR. Of +course, \f(CW%subr\fR is not complete, it contains only operators used in the +example below. Here is the extra-credit question: why do we need an +explicit recursion in \fBnum()\fR? (Answer is at the end of this section.) +.PP +Use this module like this: +.PP +.Vb 4 +\& require symbolic; +\& my $iter = symbolic\->new(2); # 16\-gon +\& my $side = symbolic\->new(1); +\& my $cnt = $iter; +\& +\& while ($cnt) { +\& $cnt = $cnt \- 1; # Mutator \*(Aq\-\-\*(Aq not implemented +\& $side = (sqrt(1 + $side**2) \- 1)/$side; +\& } +\& printf "%s=%f\en", $side, $side; +\& printf "pi=%f\en", $side*(2**($iter+2)); +.Ve +.PP +It prints (without so many line breaks) +.PP +.Vb 4 +\& [/ [\- [sqrt [+ 1 [** [/ [\- [sqrt [+ 1 [** [n 1] 2]]] 1] +\& [n 1]] 2]]] 1] +\& [/ [\- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]=0.198912 +\& pi=3.182598 +.Ve +.PP +The above module is very primitive. It does not implement +mutator methods (\f(CW\*(C`++\*(C'\fR, \f(CW\*(C`\-=\*(C'\fR and so on), does not do deep copying +(not required without mutators!), and implements only those arithmetic +operations which are used in the example. +.PP +To implement most arithmetic operations is easy; one should just use +the tables of operations, and change the code which fills \f(CW%subr\fR to +.PP +.Vb 12 +\& my %subr = ( \*(Aqn\*(Aq => sub {$_[0]} ); +\& foreach my $op (split " ", $overload::ops{with_assign}) { +\& $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; +\& } +\& my @bins = qw(binary 3way_comparison num_comparison str_comparison); +\& foreach my $op (split " ", "@overload::ops{ @bins }") { +\& $subr{$op} = eval "sub {shift() $op shift()}"; +\& } +\& foreach my $op (split " ", "@overload::ops{qw(unary func)}") { +\& print "defining \*(Aq$op\*(Aq\en"; +\& $subr{$op} = eval "sub {$op shift()}"; +\& } +.Ve +.PP +Since subroutines implementing assignment operators are not required +to modify their operands (see "Overloadable Operations" above), +we do not need anything special to make \f(CW\*(C`+=\*(C'\fR and friends work, +besides adding these operators to \f(CW%subr\fR and defining a copy +constructor (needed since Perl has no way to know that the +implementation of \f(CW\*(Aq+=\*(Aq\fR does not mutate the argument \- +see "Copy Constructor"). +.PP +To implement a copy constructor, add \f(CW\*(C`\*(Aq=\*(Aq => \e&cpy\*(C'\fR to \f(CW\*(C`use overload\*(C'\fR +line, and code (this code assumes that mutators change things one level +deep only, so recursive copying is not needed): +.PP +.Vb 4 +\& sub cpy { +\& my $self = shift; +\& bless [@$self], ref $self; +\& } +.Ve +.PP +To make \f(CW\*(C`++\*(C'\fR and \f(CW\*(C`\-\-\*(C'\fR work, we need to implement actual mutators, +either directly, or in \f(CW\*(C`nomethod\*(C'\fR. We continue to do things inside +\&\f(CW\*(C`nomethod\*(C'\fR, thus add +.PP +.Vb 4 +\& if ($meth eq \*(Aq++\*(Aq or $meth eq \*(Aq\-\-\*(Aq) { +\& @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference +\& return $obj; +\& } +.Ve +.PP +after the first line of \fBwrap()\fR. This is not a most effective +implementation, one may consider +.PP +.Vb 1 +\& sub inc { $_[0] = bless [\*(Aq++\*(Aq, shift, 1]; } +.Ve +.PP +instead. +.PP +As a final remark, note that one can fill \f(CW%subr\fR by +.PP +.Vb 10 +\& my %subr = ( \*(Aqn\*(Aq => sub {$_[0]} ); +\& foreach my $op (split " ", $overload::ops{with_assign}) { +\& $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; +\& } +\& my @bins = qw(binary 3way_comparison num_comparison str_comparison); +\& foreach my $op (split " ", "@overload::ops{ @bins }") { +\& $subr{$op} = eval "sub {shift() $op shift()}"; +\& } +\& foreach my $op (split " ", "@overload::ops{qw(unary func)}") { +\& $subr{$op} = eval "sub {$op shift()}"; +\& } +\& $subr{\*(Aq++\*(Aq} = $subr{\*(Aq+\*(Aq}; +\& $subr{\*(Aq\-\-\*(Aq} = $subr{\*(Aq\-\*(Aq}; +.Ve +.PP +This finishes implementation of a primitive symbolic calculator in +50 lines of Perl code. Since the numeric values of subexpressions +are not cached, the calculator is very slow. +.PP +Here is the answer for the exercise: In the case of \fBstr()\fR, we need no +explicit recursion since the overloaded \f(CW\*(C`.\*(C'\fR\-operator will fall back +to an existing overloaded operator \f(CW""\fR. Overloaded arithmetic +operators \fIdo not\fR fall back to numeric conversion if \f(CW\*(C`fallback\*(C'\fR is +not explicitly requested. Thus without an explicit recursion \fBnum()\fR +would convert \f(CW\*(C`[\*(Aq+\*(Aq, $a, $b]\*(C'\fR to \f(CW\*(C`$a + $b\*(C'\fR, which would just rebuild +the argument of \fBnum()\fR. +.PP +If you wonder why defaults for conversion are different for \fBstr()\fR and +\&\fBnum()\fR, note how easy it was to write the symbolic calculator. This +simplicity is due to an appropriate choice of defaults. One extra +note: due to the explicit recursion \fBnum()\fR is more fragile than \fBsym()\fR: +we need to explicitly check for the type of \f(CW$a\fR and \f(CW$b\fR. If components +\&\f(CW$a\fR and \f(CW$b\fR happen to be of some related type, this may lead to problems. +.SS "\fIReally\fP Symbolic Calculator" +.IX Subsection "Really Symbolic Calculator" +One may wonder why we call the above calculator symbolic. The reason +is that the actual calculation of the value of expression is postponed +until the value is \fIused\fR. +.PP +To see it in action, add a method +.PP +.Vb 5 +\& sub STORE { +\& my $obj = shift; +\& $#$obj = 1; +\& @$obj\->[0,1] = (\*(Aq=\*(Aq, shift); +\& } +.Ve +.PP +to the package \f(CW\*(C`symbolic\*(C'\fR. After this change one can do +.PP +.Vb 3 +\& my $a = symbolic\->new(3); +\& my $b = symbolic\->new(4); +\& my $c = sqrt($a**2 + $b**2); +.Ve +.PP +and the numeric value of \f(CW$c\fR becomes 5. However, after calling +.PP +.Vb 1 +\& $a\->STORE(12); $b\->STORE(5); +.Ve +.PP +the numeric value of \f(CW$c\fR becomes 13. There is no doubt now that the module +symbolic provides a \fIsymbolic\fR calculator indeed. +.PP +To hide the rough edges under the hood, provide a \fBtie()\fRd interface to the +package \f(CW\*(C`symbolic\*(C'\fR. Add methods +.PP +.Vb 3 +\& sub TIESCALAR { my $pack = shift; $pack\->new(@_) } +\& sub FETCH { shift } +\& sub nop { } # Around a bug +.Ve +.PP +(the bug, fixed in Perl 5.14, is described in "BUGS"). One can use this +new interface as +.PP +.Vb 3 +\& tie $a, \*(Aqsymbolic\*(Aq, 3; +\& tie $b, \*(Aqsymbolic\*(Aq, 4; +\& $a\->nop; $b\->nop; # Around a bug +\& +\& my $c = sqrt($a**2 + $b**2); +.Ve +.PP +Now numeric value of \f(CW$c\fR is 5. After \f(CW\*(C`$a = 12; $b = 5\*(C'\fR the numeric value +of \f(CW$c\fR becomes 13. To insulate the user of the module add a method +.PP +.Vb 1 +\& sub vars { my $p = shift; tie($_, $p), $_\->nop foreach @_; } +.Ve +.PP +Now +.PP +.Vb 3 +\& my ($a, $b); +\& symbolic\->vars($a, $b); +\& my $c = sqrt($a**2 + $b**2); +\& +\& $a = 3; $b = 4; +\& printf "c5 %s=%f\en", $c, $c; +\& +\& $a = 12; $b = 5; +\& printf "c13 %s=%f\en", $c, $c; +.Ve +.PP +shows that the numeric value of \f(CW$c\fR follows changes to the values of \f(CW$a\fR +and \f(CW$b\fR. +.SH AUTHOR +.IX Header "AUTHOR" +Ilya Zakharevich <\fIilya@math.mps.ohio\-state.edu\fR>. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +The \f(CW\*(C`overloading\*(C'\fR pragma can be used to enable or disable overloaded +operations within a lexical scope \- see overloading. +.SH DIAGNOSTICS +.IX Header "DIAGNOSTICS" +When Perl is run with the \fB\-Do\fR switch or its equivalent, overloading +induces diagnostic messages. +.PP +Using the \f(CW\*(C`m\*(C'\fR command of Perl debugger (see perldebug) one can +deduce which operations are overloaded (and which ancestor triggers +this overloading). Say, if \f(CW\*(C`eq\*(C'\fR is overloaded, then the method \f(CW\*(C`(eq\*(C'\fR +is shown by debugger. The method \f(CW\*(C`()\*(C'\fR corresponds to the \f(CW\*(C`fallback\*(C'\fR +key (in fact a presence of this method shows that this package has +overloading enabled, and it is what is used by the \f(CW\*(C`Overloaded\*(C'\fR +function of module \f(CW\*(C`overload\*(C'\fR). +.PP +The module might issue the following warnings: +.IP "Odd number of arguments for overload::constant" 4 +.IX Item "Odd number of arguments for overload::constant" +(W) The call to overload::constant contained an odd number of arguments. +The arguments should come in pairs. +.IP "'%s' is not an overloadable type" 4 +.IX Item "'%s' is not an overloadable type" +(W) You tried to overload a constant type the overload package is unaware of. +.IP "'%s' is not a code reference" 4 +.IX Item "'%s' is not a code reference" +(W) The second (fourth, sixth, ...) argument of overload::constant needs +to be a code reference. Either an anonymous subroutine, or a reference +to a subroutine. +.IP "overload arg '%s' is invalid" 4 +.IX Item "overload arg '%s' is invalid" +(W) \f(CW\*(C`use overload\*(C'\fR was passed an argument it did not +recognize. Did you mistype an operator? +.SH "BUGS AND PITFALLS" +.IX Header "BUGS AND PITFALLS" +.IP \(bu 4 +A pitfall when fallback is TRUE and Perl resorts to a built-in +implementation of an operator is that some operators have more +than one semantic, for example \f(CW\*(C`|\*(C'\fR: +.Sp +.Vb 5 +\& use overload \*(Aq0+\*(Aq => sub { $_[0]\->{n}; }, +\& fallback => 1; +\& my $x = bless { n => 4 }, "main"; +\& my $y = bless { n => 8 }, "main"; +\& print $x | $y, "\en"; +.Ve +.Sp +You might expect this to output "12". +In fact, it prints "<": the ASCII result of treating "|" +as a bitwise string operator \- that is, the result of treating +the operands as the strings "4" and "8" rather than numbers. +The fact that numify (\f(CW\*(C`0+\*(C'\fR) is implemented but stringify +(\f(CW""\fR) isn't makes no difference since the latter is simply +autogenerated from the former. +.Sp +The only way to change this is to provide your own subroutine +for \f(CW\*(Aq|\*(Aq\fR. +.IP \(bu 4 +Magic autogeneration increases the potential for inadvertently +creating self-referential structures. +Currently Perl will not free self-referential +structures until cycles are explicitly broken. +For example, +.Sp +.Vb 2 +\& use overload \*(Aq+\*(Aq => \*(Aqadd\*(Aq; +\& sub add { bless [ \e$_[0], \e$_[1] ] }; +.Ve +.Sp +is asking for trouble, since +.Sp +.Vb 1 +\& $obj += $y; +.Ve +.Sp +will effectively become +.Sp +.Vb 1 +\& $obj = add($obj, $y, undef); +.Ve +.Sp +with the same result as +.Sp +.Vb 1 +\& $obj = [\e$obj, \e$foo]; +.Ve +.Sp +Even if no \fIexplicit\fR assignment-variants of operators are present in +the script, they may be generated by the optimizer. +For example, +.Sp +.Vb 1 +\& "obj = $obj\en" +.Ve +.Sp +may be optimized to +.Sp +.Vb 1 +\& my $tmp = \*(Aqobj = \*(Aq . $obj; $tmp .= "\en"; +.Ve +.IP \(bu 4 +The symbol table is filled with names looking like line-noise. +.IP \(bu 4 +This bug was fixed in Perl 5.18, but may still trip you up if you are using +older versions: +.Sp +For the purpose of inheritance every overloaded package behaves as if +\&\f(CW\*(C`fallback\*(C'\fR is present (possibly undefined). This may create +interesting effects if some package is not overloaded, but inherits +from two overloaded packages. +.IP \(bu 4 +Before Perl 5.14, the relation between overloading and \fBtie()\fRing was broken. +Overloading was triggered or not based on the \fIprevious\fR class of the +\&\fBtie()\fRd variable. +.Sp +This happened because the presence of overloading was checked +too early, before any \fBtie()\fRd access was attempted. If the +class of the value \fBFETCH()\fRed from the tied variable does not +change, a simple workaround for code that is to run on older Perl +versions is to access the value (via \f(CW\*(C`() = $foo\*(C'\fR or some such) +immediately after \fBtie()\fRing, so that after this call the \fIprevious\fR class +coincides with the current one. +.IP \(bu 4 +Barewords are not covered by overloaded string constants. +.IP \(bu 4 +The range operator \f(CW\*(C`..\*(C'\fR cannot be overloaded. |