add link for those who look at overload for overriding
[p5sagit/p5-mst-13.2.git] / lib / overload.pm
index 0120882..2c0c8f9 100644 (file)
@@ -1,6 +1,6 @@
 package overload;
 
-our $VERSION = '1.04';
+our $VERSION = '1.07';
 
 sub nil {}
 
@@ -72,7 +72,13 @@ sub OverloadedStringify {
 
 sub Method {
   my $package = shift;
-  $package = ref $package if ref $package;
+  if(ref $package) {
+    local $@;
+    local $!;
+    require Scalar::Util;
+    $package = Scalar::Util::blessed($package);
+    return undef if !defined $package;
+  }
   #my $meth = $package->can('(' . shift);
   ov_method mycan($package, '(' . shift), $package;
   #return $meth if $meth ne \&nil;
@@ -83,24 +89,31 @@ sub AddrRef {
   my $package = ref $_[0];
   return "$_[0]" unless $package;
 
-       require Scalar::Util;
-       my $class = Scalar::Util::blessed($_[0]);
-       my $class_prefix = defined($class) ? "$class=" : "";
-       my $type = Scalar::Util::reftype($_[0]);
-       my $addr = Scalar::Util::refaddr($_[0]);
-       return sprintf("$class_prefix$type(0x%x)", $addr);
+  local $@;
+  local $!;
+  require Scalar::Util;
+  my $class = Scalar::Util::blessed($_[0]);
+  my $class_prefix = defined($class) ? "$class=" : "";
+  my $type = Scalar::Util::reftype($_[0]);
+  my $addr = Scalar::Util::refaddr($_[0]);
+  return sprintf("$class_prefix$type(0x%x)", $addr);
 }
 
 *StrVal = *AddrRef;
 
 sub mycan {                            # Real can would leave stubs.
   my ($package, $meth) = @_;
-  return \*{$package . "::$meth"} if defined &{$package . "::$meth"};
-  my $p;
-  foreach $p (@{$package . "::ISA"}) {
-    my $out = mycan($p, $meth);
-    return $out if $out;
+
+  local $@;
+  local $!;
+  require mro;
+
+  my $mro = mro::get_linear_isa($package);
+  foreach my $p (@$mro) {
+    my $fqmeth = $p . q{::} . $meth;
+    return \*{$fqmeth} if defined &{$fqmeth};
   }
+
   return undef;
 }
 
@@ -117,7 +130,7 @@ sub mycan {                         # Real can would leave stubs.
         num_comparison   => "< <= >  >= == !=",
         '3way_comparison'=> "<=> cmp",
         str_comparison   => "lt le gt ge eq ne",
-        binary           => "& | ^",
+        binary           => '& &= | |= ^ ^=',
         unary            => "neg ! ~",
         mutators         => '++ --',
         func             => "atan2 cos sin exp abs log sqrt int",
@@ -137,7 +150,7 @@ sub constant {
     elsif (!exists $constants {$_ [0]}) {
         warnings::warnif ("`$_[0]' is not an overloadable type");
     }
-    elsif (!ref $_ [1] || "$_[1]" !~ /CODE\(0x[\da-f]+\)$/) {
+    elsif (!ref $_ [1] || "$_[1]" !~ /(^|=)CODE\(0x[0-9a-f]+\)$/) {
         # Can't use C<ref $_[1] eq "CODE"> above as code references can be
         # blessed, and C<ref> would return the package the ref is blessed into.
         if (warnings::enabled) {
@@ -181,7 +194,7 @@ overload - Package for overloading Perl operations
     ...
 
     package main;
-    $a = new SomeThing 57;
+    $a = SomeThing->new( 57 );
     $b=5+$a;
     ...
     if (overload::Overloaded $b) {...}
@@ -190,6 +203,9 @@ overload - Package for overloading Perl operations
 
 =head1 DESCRIPTION
 
+This pragma allows overloading of Perl's operators for a class.
+To overload built-in functions, see L<perlsub/Overriding Built-in Functions> instead.
+
 =head2 Declaration of overloaded functions
 
 The compilation directive
@@ -350,13 +366,17 @@ arrays, C<cmp> is used to compare values subject to C<use overload>.
 
 =item * I<Bit operations>
 
-    "&", "^", "|", "neg", "!", "~",
+    "&", "&=", "^", "^=", "|", "|=", "neg", "!", "~",
 
 C<neg> stands for unary minus.  If the method for C<neg> is not
 specified, it can be autogenerated using the method for
 subtraction. If the method for C<!> is not specified, it can be
 autogenerated using the methods for C<bool>, or C<"">, or C<0+>.
 
+The same remarks in L<"Arithmetic operations"> about
+assignment-variants and autogeneration apply for
+bit operations C<"&">, C<"^">, and C<"|"> as well.
+
 =item * I<Increment and decrement>
 
     "++", "--",
@@ -437,7 +457,7 @@ A computer-readable form of the above table is available in the hash
  num_comparison          => '< <= > >= == !=',
  '3way_comparison'=> '<=> cmp',
  str_comparison          => 'lt le gt ge eq ne',
- binary                  => '& | ^',
+ binary                  => '& &= | |= ^ ^=',
  unary           => 'neg ! ~',
  mutators        => '++ --',
  func            => 'atan2 cos sin exp abs log sqrt',
@@ -575,7 +595,8 @@ appear as lvalue when the above code is executed.
 
 If the copy constructor is required during the execution of some mutator,
 but a method for C<'='> was not specified, it can be autogenerated as a
-string copy if the object is a plain scalar.
+string copy if the object is a plain scalar or a simple assignment if it
+is not.
 
 =over 5
 
@@ -662,7 +683,8 @@ C<E<lt>=E<gt>> or C<cmp>:
 =item I<Copy operator>
 
 can be expressed in terms of an assignment to the dereferenced value, if this
-value is a scalar and not a reference.
+value is a scalar and not a reference, or simply a reference assignment
+otherwise.
 
 =back
 
@@ -883,7 +905,7 @@ If some mutator methods are directly applied to the overloaded values,
 one may need to I<explicitly unlink> other values which references the
 same value:
 
-    $a = new Data 23;
+    $a = Data->new(23);
     ...
     $b = $a;           # $b is "linked" to $a
     ...
@@ -892,13 +914,13 @@ same value:
 
 Note that overloaded access makes this transparent:
 
-    $a = new Data 23;
+    $a = Data->new(23);
     $b = $a;           # $b is "linked" to $a
     $a += 4;           # would unlink $b automagically
 
 However, it would not make
 
-    $a = new Data 23;
+    $a = Data->new(23);
     $a = 4;            # Now $a is a plain 4, not 'Data'
 
 preserve "objectness" of $a.  But Perl I<has> a way to make assignments
@@ -928,7 +950,7 @@ Put this in F<two_face.pm> in your Perl library directory:
 Use it as follows:
 
   require two_face;
-  my $seven = new two_face ("vii", 7);
+  my $seven = two_face->new("vii", 7);
   printf "seven=$seven, seven=%d, eight=%d\n", $seven, $seven+1;
   print "seven contains `i'\n" if $seven =~ /i/;
 
@@ -975,7 +997,7 @@ array reference and a hash reference.
 
 Now one can access an object using both the array and hash syntax:
 
-  my $bar = new two_refs 3,4,5,6;
+  my $bar = two_refs->new(3,4,5,6);
   $bar->[2] = 11;
   $bar->{two} == 11 or die 'bad hash fetch';
 
@@ -1080,15 +1102,15 @@ This module is very unusual as overloaded modules go: it does not
 provide any usual overloaded operators, instead it provides the L<Last
 Resort> operator C<nomethod>.  In this example the corresponding
 subroutine returns an object which encapsulates operations done over
-the objects: C<new symbolic 3> contains C<['n', 3]>, C<2 + new
-symbolic 3> contains C<['+', 2, ['n', 3]]>.
+the objects: C<< symbolic->new(3) >> contains C<['n', 3]>, C<< 2 +
+symbolic->new(3) >> contains C<['+', 2, ['n', 3]]>.
 
 Here is an example of the script which "calculates" the side of
 circumscribed octagon using the above package:
 
   require symbolic;
   my $iter = 1;                        # 2**($iter+2) = 8
-  my $side = new symbolic 1;
+  my $side = symbolic->new(1);
   my $cnt = $iter;
 
   while ($cnt--) {
@@ -1103,7 +1125,7 @@ The value of $side is
 
 Note that while we obtained this value using a nice little script,
 there is no simple way to I<use> this value.  In fact this value may
-be inspected in debugger (see L<perldebug>), but ony if
+be inspected in debugger (see L<perldebug>), but only if
 C<bareStringify> B<O>ption is set, and not via C<p> command.
 
 If one attempts to print this value, then the overloaded operator
@@ -1212,8 +1234,8 @@ explicit recursion in num()?  (Answer is at the end of this section.)
 Use this module like this:
 
   require symbolic;
-  my $iter = new symbolic 2;   # 16-gon
-  my $side = new symbolic 1;
+  my $iter = symbolic->new(2); # 16-gon
+  my $side = symbolic->new(1);
   my $cnt = $iter;
 
   while ($cnt) {
@@ -1333,8 +1355,8 @@ To see it in action, add a method
 
 to the package C<symbolic>.  After this change one can do
 
-  my $a = new symbolic 3;
-  my $b = new symbolic 4;
+  my $a = symbolic->new(3);
+  my $b = symbolic->new(4);
   my $c = sqrt($a**2 + $b**2);
 
 and the numeric value of $c becomes 5.  However, after calling
@@ -1383,6 +1405,11 @@ and $b.
 
 Ilya Zakharevich E<lt>F<ilya@math.mps.ohio-state.edu>E<gt>.
 
+=head1 SEE ALSO
+
+The L<overloading> pragma can be used to enable or disable overloaded
+operations within a lexical scope.
+
 =head1 DIAGNOSTICS
 
 When Perl is run with the B<-Do> switch or its equivalent, overloading