source: trunk/essentials/dev-lang/perl/lib/overload.pm@ 3310

Last change on this file since 3310 was 3181, checked in by bird, 19 years ago

perl 5.8.8

File size: 44.9 KB
Line 
1package overload;
2
3our $VERSION = '1.04';
4
5$overload::hint_bits = 0x20000; # HINT_LOCALIZE_HH
6
7sub nil {}
8
9sub OVERLOAD {
10 $package = shift;
11 my %arg = @_;
12 my ($sub, $fb);
13 $ {$package . "::OVERLOAD"}{dummy}++; # Register with magic by touching.
14 *{$package . "::()"} = \&nil; # Make it findable via fetchmethod.
15 for (keys %arg) {
16 if ($_ eq 'fallback') {
17 $fb = $arg{$_};
18 } else {
19 $sub = $arg{$_};
20 if (not ref $sub and $sub !~ /::/) {
21 $ {$package . "::(" . $_} = $sub;
22 $sub = \&nil;
23 }
24 #print STDERR "Setting `$ {'package'}::\cO$_' to \\&`$sub'.\n";
25 *{$package . "::(" . $_} = \&{ $sub };
26 }
27 }
28 ${$package . "::()"} = $fb; # Make it findable too (fallback only).
29}
30
31sub import {
32 $package = (caller())[0];
33 # *{$package . "::OVERLOAD"} = \&OVERLOAD;
34 shift;
35 $package->overload::OVERLOAD(@_);
36}
37
38sub unimport {
39 $package = (caller())[0];
40 ${$package . "::OVERLOAD"}{dummy}++; # Upgrade the table
41 shift;
42 for (@_) {
43 if ($_ eq 'fallback') {
44 undef $ {$package . "::()"};
45 } else {
46 delete $ {$package . "::"}{"(" . $_};
47 }
48 }
49}
50
51sub Overloaded {
52 my $package = shift;
53 $package = ref $package if ref $package;
54 $package->can('()');
55}
56
57sub ov_method {
58 my $globref = shift;
59 return undef unless $globref;
60 my $sub = \&{*$globref};
61 return $sub if $sub ne \&nil;
62 return shift->can($ {*$globref});
63}
64
65sub OverloadedStringify {
66 my $package = shift;
67 $package = ref $package if ref $package;
68 #$package->can('(""')
69 ov_method mycan($package, '(""'), $package
70 or ov_method mycan($package, '(0+'), $package
71 or ov_method mycan($package, '(bool'), $package
72 or ov_method mycan($package, '(nomethod'), $package;
73}
74
75sub Method {
76 my $package = shift;
77 $package = ref $package if ref $package;
78 #my $meth = $package->can('(' . shift);
79 ov_method mycan($package, '(' . shift), $package;
80 #return $meth if $meth ne \&nil;
81 #return $ {*{$meth}};
82}
83
84sub AddrRef {
85 my $package = ref $_[0];
86 return "$_[0]" unless $package;
87
88 require Scalar::Util;
89 my $class = Scalar::Util::blessed($_[0]);
90 my $class_prefix = defined($class) ? "$class=" : "";
91 my $type = Scalar::Util::reftype($_[0]);
92 my $addr = Scalar::Util::refaddr($_[0]);
93 return sprintf("$class_prefix$type(0x%x)", $addr);
94}
95
96*StrVal = *AddrRef;
97
98sub mycan { # Real can would leave stubs.
99 my ($package, $meth) = @_;
100 return \*{$package . "::$meth"} if defined &{$package . "::$meth"};
101 my $p;
102 foreach $p (@{$package . "::ISA"}) {
103 my $out = mycan($p, $meth);
104 return $out if $out;
105 }
106 return undef;
107}
108
109%constants = (
110 'integer' => 0x1000, # HINT_NEW_INTEGER
111 'float' => 0x2000, # HINT_NEW_FLOAT
112 'binary' => 0x4000, # HINT_NEW_BINARY
113 'q' => 0x8000, # HINT_NEW_STRING
114 'qr' => 0x10000, # HINT_NEW_RE
115 );
116
117%ops = ( with_assign => "+ - * / % ** << >> x .",
118 assign => "+= -= *= /= %= **= <<= >>= x= .=",
119 num_comparison => "< <= > >= == !=",
120 '3way_comparison'=> "<=> cmp",
121 str_comparison => "lt le gt ge eq ne",
122 binary => "& | ^",
123 unary => "neg ! ~",
124 mutators => '++ --',
125 func => "atan2 cos sin exp abs log sqrt int",
126 conversion => 'bool "" 0+',
127 iterators => '<>',
128 dereferencing => '${} @{} %{} &{} *{}',
129 special => 'nomethod fallback =');
130
131use warnings::register;
132sub constant {
133 # Arguments: what, sub
134 while (@_) {
135 if (@_ == 1) {
136 warnings::warnif ("Odd number of arguments for overload::constant");
137 last;
138 }
139 elsif (!exists $constants {$_ [0]}) {
140 warnings::warnif ("`$_[0]' is not an overloadable type");
141 }
142 elsif (!ref $_ [1] || "$_[1]" !~ /CODE\(0x[\da-f]+\)$/) {
143 # Can't use C<ref $_[1] eq "CODE"> above as code references can be
144 # blessed, and C<ref> would return the package the ref is blessed into.
145 if (warnings::enabled) {
146 $_ [1] = "undef" unless defined $_ [1];
147 warnings::warn ("`$_[1]' is not a code reference");
148 }
149 }
150 else {
151 $^H{$_[0]} = $_[1];
152 $^H |= $constants{$_[0]} | $overload::hint_bits;
153 }
154 shift, shift;
155 }
156}
157
158sub remove_constant {
159 # Arguments: what, sub
160 while (@_) {
161 delete $^H{$_[0]};
162 $^H &= ~ $constants{$_[0]};
163 shift, shift;
164 }
165}
166
1671;
168
169__END__
170
171=head1 NAME
172
173overload - Package for overloading Perl operations
174
175=head1 SYNOPSIS
176
177 package SomeThing;
178
179 use overload
180 '+' => \&myadd,
181 '-' => \&mysub;
182 # etc
183 ...
184
185 package main;
186 $a = new SomeThing 57;
187 $b=5+$a;
188 ...
189 if (overload::Overloaded $b) {...}
190 ...
191 $strval = overload::StrVal $b;
192
193=head1 DESCRIPTION
194
195=head2 Declaration of overloaded functions
196
197The compilation directive
198
199 package Number;
200 use overload
201 "+" => \&add,
202 "*=" => "muas";
203
204declares function Number::add() for addition, and method muas() in
205the "class" C<Number> (or one of its base classes)
206for the assignment form C<*=> of multiplication.
207
208Arguments of this directive come in (key, value) pairs. Legal values
209are values legal inside a C<&{ ... }> call, so the name of a
210subroutine, a reference to a subroutine, or an anonymous subroutine
211will all work. Note that values specified as strings are
212interpreted as methods, not subroutines. Legal keys are listed below.
213
214The subroutine C<add> will be called to execute C<$a+$b> if $a
215is a reference to an object blessed into the package C<Number>, or if $a is
216not an object from a package with defined mathemagic addition, but $b is a
217reference to a C<Number>. It can also be called in other situations, like
218C<$a+=7>, or C<$a++>. See L<MAGIC AUTOGENERATION>. (Mathemagical
219methods refer to methods triggered by an overloaded mathematical
220operator.)
221
222Since overloading respects inheritance via the @ISA hierarchy, the
223above declaration would also trigger overloading of C<+> and C<*=> in
224all the packages which inherit from C<Number>.
225
226=head2 Calling Conventions for Binary Operations
227
228The functions specified in the C<use overload ...> directive are called
229with three (in one particular case with four, see L<Last Resort>)
230arguments. If the corresponding operation is binary, then the first
231two arguments are the two arguments of the operation. However, due to
232general object calling conventions, the first argument should always be
233an object in the package, so in the situation of C<7+$a>, the
234order of the arguments is interchanged. It probably does not matter
235when implementing the addition method, but whether the arguments
236are reversed is vital to the subtraction method. The method can
237query this information by examining the third argument, which can take
238three different values:
239
240=over 7
241
242=item FALSE
243
244the order of arguments is as in the current operation.
245
246=item TRUE
247
248the arguments are reversed.
249
250=item C<undef>
251
252the current operation is an assignment variant (as in
253C<$a+=7>), but the usual function is called instead. This additional
254information can be used to generate some optimizations. Compare
255L<Calling Conventions for Mutators>.
256
257=back
258
259=head2 Calling Conventions for Unary Operations
260
261Unary operation are considered binary operations with the second
262argument being C<undef>. Thus the functions that overloads C<{"++"}>
263is called with arguments C<($a,undef,'')> when $a++ is executed.
264
265=head2 Calling Conventions for Mutators
266
267Two types of mutators have different calling conventions:
268
269=over
270
271=item C<++> and C<-->
272
273The routines which implement these operators are expected to actually
274I<mutate> their arguments. So, assuming that $obj is a reference to a
275number,
276
277 sub incr { my $n = $ {$_[0]}; ++$n; $_[0] = bless \$n}
278
279is an appropriate implementation of overloaded C<++>. Note that
280
281 sub incr { ++$ {$_[0]} ; shift }
282
283is OK if used with preincrement and with postincrement. (In the case
284of postincrement a copying will be performed, see L<Copy Constructor>.)
285
286=item C<x=> and other assignment versions
287
288There is nothing special about these methods. They may change the
289value of their arguments, and may leave it as is. The result is going
290to be assigned to the value in the left-hand-side if different from
291this value.
292
293This allows for the same method to be used as overloaded C<+=> and
294C<+>. Note that this is I<allowed>, but not recommended, since by the
295semantic of L<"Fallback"> Perl will call the method for C<+> anyway,
296if C<+=> is not overloaded.
297
298=back
299
300B<Warning.> Due to the presence of assignment versions of operations,
301routines which may be called in assignment context may create
302self-referential structures. Currently Perl will not free self-referential
303structures until cycles are C<explicitly> broken. You may get problems
304when traversing your structures too.
305
306Say,
307
308 use overload '+' => sub { bless [ \$_[0], \$_[1] ] };
309
310is asking for trouble, since for code C<$obj += $foo> the subroutine
311is called as C<$obj = add($obj, $foo, undef)>, or C<$obj = [\$obj,