This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
CGI.pm broke again
[perl5.git] / lib / overload.pm
index 3c9562a..c9044db 100644 (file)
@@ -1,12 +1,27 @@
 package overload;
 
+sub nil {}
+
 sub OVERLOAD {
   $package = shift;
   my %arg = @_;
-  my $hash = \%{$package . "::OVERLOAD"};
+  my ($sub, $fb);
+  $ {$package . "::OVERLOAD"}{dummy}++; # Register with magic by touching.
+  *{$package . "::()"} = \&nil; # Make it findable via fetchmethod.
   for (keys %arg) {
-    $hash->{$_} = $arg{$_};
+    if ($_ eq 'fallback') {
+      $fb = $arg{$_};
+    } else {
+      $sub = $arg{$_};
+      if (not ref $sub and $sub !~ /::/) {
+       $ {$package . "::(" . $_} = $sub;
+       $sub = \&nil;
+      }
+      #print STDERR "Setting `$ {'package'}::\cO$_' to \\&`$sub'.\n";
+      *{$package . "::(" . $_} = \&{ $sub };
+    }
   }
+  ${$package . "::()"} = $fb; # Make it findable too (fallback only).
 }
 
 sub import {
@@ -18,51 +33,80 @@ sub import {
 
 sub unimport {
   $package = (caller())[0];
-  my $hash = \%{$package . "::OVERLOAD"};
+  ${$package . "::OVERLOAD"}{dummy}++; # Upgrade the table
   shift;
   for (@_) {
-    delete $hash->{$_};
+    if ($_ eq 'fallback') {
+      undef $ {$package . "::()"};
+    } else {
+      delete $ {$package . "::"}{"(" . $_};
+    }
   }
 }
 
 sub Overloaded {
-  defined ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"};
+  my $package = shift;
+  $package = ref $package if ref $package;
+  $package->can('()');
+}
+
+sub ov_method {
+  my $globref = shift;
+  return undef unless $globref;
+  my $sub = \&{*$globref};
+  return $sub if $sub ne \&nil;
+  return shift->can($ {*$globref});
 }
 
 sub OverloadedStringify {
-  defined ($package = ref $_[0]) and 
-    defined %{$package . "::OVERLOAD"} and 
-      exists $ {$package . "::OVERLOAD"}{'""'} and
-       defined &{$ {$package . "::OVERLOAD"}{'""'}};
+  my $package = shift;
+  $package = ref $package if ref $package;
+  #$package->can('(""')
+  ov_method mycan($package, '(""'), $package;
 }
 
 sub Method {
-  defined ($package = ref $_[0]) and 
-    defined %{$package . "::OVERLOAD"} and 
-      $ {$package . "::OVERLOAD"}{$_[1]};
+  my $package = shift;
+  $package = ref $package if ref $package;
+  #my $meth = $package->can('(' . shift);
+  ov_method mycan($package, '(' . shift), $package;
+  #return $meth if $meth ne \&nil;
+  #return $ {*{$meth}};
 }
 
 sub AddrRef {
-  $package = ref $_[0];
-  bless $_[0], Overload::Fake; # Non-overloaded package
+  my $package = ref $_[0];
+  return "$_[0]" unless $package;
+  bless $_[0], overload::Fake; # Non-overloaded package
   my $str = "$_[0]";
   bless $_[0], $package;       # Back
-  $str;
+  $package . substr $str, index $str, '=';
 }
 
 sub StrVal {
-  (OverloadedStringify) ?
-    (AddrRef) :
+  (OverloadedStringify($_[0])) ?
+    (AddrRef(shift)) :
     "$_[0]";
 }
 
+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;
+  }
+  return undef;
+}
+
 1;
 
 __END__
 
 =head1 NAME 
 
-C<overload.pm> - Package for overloading perl operations
+overload - Package for overloading perl operations
 
 =head1 SYNOPSIS
 
@@ -105,9 +149,10 @@ the "class" C<Number> (or one of its base classes)
 for the assignment form C<*=> of multiplication.  
 
 Arguments of this directive come in (key, value) pairs.  Legal values
-are values legal inside a C<&{ ... }> call, so the name of a subroutine,
-a reference to a subroutine, or an anonymous subroutine will all work.
-Legal keys are listed below.
+are values legal inside a C<&{ ... }> call, so the name of a
+subroutine, a reference to a subroutine, or an anonymous subroutine
+will all work.  Note that values specified as strings are
+interpreted as methods, not subroutines.  Legal keys are listed below.
 
 The subroutine C<add> will be called to execute C<$a+$b> if $a
 is a reference to an object blessed into the package C<Number>, or if $a is
@@ -117,6 +162,10 @@ C<$a+=7>, or C<$a++>.  See L<MAGIC AUTOGENERATION>.  (Mathemagical
 methods refer to methods triggered by an overloaded mathematical
 operator.)
 
+Since overloading respects inheritance via the @ISA hierarchy, the
+above declaration would also trigger overloading of C<+> and C<*=> in
+all the packages which inherit from C<Number>.
+
 =head2 Calling Conventions for Binary Operations
 
 The functions specified in the C<use overload ...> directive are called
@@ -186,7 +235,9 @@ arrays, C<cmp> is used to compare values subject to C<use overload>.
     "&", "^", "|", "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.
+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+>".
 
 =item * I<Increment and decrement>
 
@@ -201,7 +252,7 @@ postfix form.
     "atan2", "cos", "sin", "exp", "abs", "log", "sqrt",
 
 If C<abs> is unavailable, it can be autogenerated using methods
-for "<" or "<=>" combined with either unary minus or subtraction.
+for "E<lt>" or "E<lt>=E<gt>" combined with either unary minus or subtraction.
 
 =item * I<Boolean, string and numeric conversion>
 
@@ -223,12 +274,46 @@ see L<SPECIAL SYMBOLS FOR C<use overload>>.
 
 See L<"Fallback"> for an explanation of when a missing method can be autogenerated.
 
+=head2 Inheritance and overloading
+
+Inheritance interacts with overloading in two ways.
+
+=over
+
+=item Strings as values of C<use overload> directive
+
+If C<value> in
+
+  use overload key => value;
+
+is a string, it is interpreted as a method name.
+
+=item Overloading of an operation is inherited by derived classes
+
+Any class derived from an overloaded class is also overloaded.  The
+set of overloaded methods is the union of overloaded methods of all
+the ancestors. If some method is overloaded in several ancestor, then
+which description will be used is decided by the usual inheritance
+rules:
+
+If C<A> inherits from C<B> and C<C> (in this order), C<B> overloads
+C<+> with C<\&D::plus_sub>, and C<C> overloads C<+> by C<"plus_meth">,
+then the subroutine C<D::plus_sub> will be called to implement
+operation C<+> for an object in package C<A>.
+
+=back
+
+Note that since the value of the C<fallback> key is not a subroutine,
+its inheritance is not governed by the above rules.  In the current
+implementation, the value of C<fallback> in the first overloaded
+ancestor is used, but this is accidental and subject to change.
+
 =head1 SPECIAL SYMBOLS FOR C<use overload>
 
 Three keys are recognized by Perl that are not covered by the above
 description.
 
-=head2  Last Resort
+=head2 Last Resort
 
 C<"nomethod"> should be followed by a reference to a function of four
 parameters.  If defined, it is called when the overloading mechanism
@@ -275,6 +360,9 @@ C<"nomethod"> value, and if this is missing, raises an exception.
 
 =back
 
+B<Note.> C<"fallback"> inheritance via @ISA is not carved in stone
+yet, see L<"Inheritance and overloading">.
+
 =head2 Copy Constructor
 
 The value for C<"="> is a reference to a function with three
@@ -361,6 +449,11 @@ can be expressed in terms of C<$aE<lt>0> and C<-$a> (or C<0-$a>).
 
 can be expressed in terms of subtraction.
 
+=item I<Negation>
+
+C<!> and C<not> can be expressed in terms of boolean conversion, or
+string or numerical conversion.
+
 =item I<Concatenation>
 
 can be expressed in terms of string conversion.
@@ -369,7 +462,7 @@ can be expressed in terms of string conversion.
 
 can be expressed in terms of its "spaceship" counterpart: either
 C<E<lt>=E<gt>> or C<cmp>:
+
     <, >, <=, >=, ==, !=       in terms of <=>
     lt, gt, le, ge, eq, ne     in terms of cmp
 
@@ -433,31 +526,40 @@ Returns C<undef> or a reference to the method that implements C<op>.
 
 What follows is subject to change RSN.
 
-The table of methods for all operations is cached as magic in the
-symbol table hash for the package.  The table is rechecked for changes due to
-C<use overload>, C<no overload>, and @ISA only during
-C<bless>ing; so if they are changed dynamically, you'll need an
-additional fake C<bless>ing to update the table.
-
-(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 %ENV magic and their taint magic.)
+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 C<use overload>, C<no overload>, new function
+definitions, and changes in @ISA. However, this invalidation remains
+unprocessed until the next C<bless>ing into the package. Hence if you
+want to change overloading structure dynamically, you'll need an
+additional (fake) C<bless>ing to update the table.
+
+(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 %ENV 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.)
 
 If an object belongs to a package using overload, it carries a special
 flag.  Thus the only speed penalty during arithmetic operations without
 overloading is the checking of this flag.
 
-In fact, if C<use overload> is not present, there is almost no overhead for
-overloadable operations, so most programs should not suffer measurable
-performance penalties.  A considerable effort was made to minimize the overhead
-when overload is used and the current operation is overloadable but
-the arguments in question do not belong to packages using overload.  When
-in doubt, test your speed with C<use overload> and without it.  So far there
-have been no reports of substantial speed degradation if Perl is compiled
-with optimization turned on.
-
-There is no size penalty for data if overload is not used. 
+In fact, if C<use overload> is not present, there is almost no overhead
+for overloadable operations, so most programs should not suffer
+measurable performance penalties.  A considerable effort was made to
+minimize the overhead when overload is used in some package, but the
+arguments in question do not belong to packages using overload.  When
+in doubt, test your speed with C<use overload> and without it.  So far
+there have been no reports of substantial speed degradation if Perl is
+compiled with optimization turned on.
+
+There is no size penalty for data if overload is not used. The only
+size penalty if overload is used in some package is that I<all> the
+packages acquire a magic during the next C<bless>ing into the
+package. This magic is three-words-long for packages without
+overloading, and carries the cache tabel if the package is overloaded.
 
 Copying (C<$a=$b>) is shallow; however, a one-level-deep copying is 
 carried out before any operation that can imply an assignment to the
@@ -469,19 +571,31 @@ to be changed are constant (but this is not enforced).
 
 =head1 AUTHOR
 
-Ilya Zakharevich <F<ilya@math.mps.ohio-state.edu>>.
+Ilya Zakharevich E<lt>F<ilya@math.mps.ohio-state.edu>E<gt>.
 
 =head1 DIAGNOSTICS
 
 When Perl is run with the B<-Do> switch or its equivalent, overloading
 induces diagnostic messages.
 
+Using the C<m> command of Perl debugger (see L<perldebug>) one can
+deduce which operations are overloaded (and which ancestor triggers
+this overloading). Say, if C<eq> is overloaded, then the method C<(eq>
+is shown by debugger. The method C<()> corresponds to the C<fallback>
+key (in fact a presence of this method shows that this package has
+overloading enabled, and it is what is used by the C<Overloaded>
+function).
+
 =head1 BUGS
 
-Because it is used for overloading, the per-package associative array
-%OVERLOAD now has a special meaning in Perl.
+Because it is used for overloading, the per-package hash %OVERLOAD now
+has a special meaning in Perl. The symbol table is filled with names
+looking like line-noise.
 
-As shipped, mathemagical properties are not inherited via the @ISA tree.
+For the purpose of inheritance every overloaded package behaves as if
+C<fallback> is present (possibly undefined). This may create
+interesting effects if some package is not overloaded, but inherits
+from two overloaded packages.
 
 This document is confusing.