added patch for overloading constants, made PERL_OBJECT-aware
[p5sagit/p5-mst-13.2.git] / lib / overload.pm
index 2bbb639..dfcdb02 100644 (file)
@@ -100,6 +100,32 @@ sub mycan {                                # Real can would leave stubs.
   return undef;
 }
 
+%constants = (
+             'integer'   =>  0x1000, 
+             'float'     =>  0x2000,
+             'binary'    =>  0x4000,
+             'q'         =>  0x8000,
+             'qr'        => 0x10000,
+            );
+
+sub constant {
+  # Arguments: what, sub
+  while (@_) {
+    $^H{$_[0]} = $_[1];
+    $^H |= $constants{$_[0]} | 0x20000;
+    shift, shift;
+  }
+}
+
+sub remove_constant {
+  # Arguments: what, sub
+  while (@_) {
+    delete $^H{$_[0]};
+    $^H &= ~ $constants{$_[0]};
+    shift, shift;
+  }
+}
+
 1;
 
 __END__
@@ -162,9 +188,9 @@ C<$a+=7>, or C<$a++>.  See L<MAGIC AUTOGENERATION>.  (Mathemagical
 methods refer to methods triggered by an overloaded mathematical
 operator.)
 
-Since overloading respects @ISA hierarchy, in fact the above
-declaration would also trigger overloading of C<+> and C<*=> in all
-the packages which inherit from C<Number>.
+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
 
@@ -276,44 +302,44 @@ See L<"Fallback"> for an explanation of when a missing method can be autogenerat
 
 =head2 Inheritance and overloading
 
-There are two ways how inheritance interacts with overloading. 
+Inheritance interacts with overloading in two ways.
 
 =over
 
 =item Strings as values of C<use overload> directive
 
-If the value of 
+If C<value> in
 
   use overload key => value;
 
-directive is a string, it is interpreted as a method name.
+is a string, it is interpreted as a method name.
 
 =item Overloading of an operation is inherited by derived classes
 
-If any of ancestors is overloaded, so is the derived class. The set of
-overloaded methods is the union of overloaded methods of all the
-ancestors. If some method is overloaded in several ancestor, then
+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: 
+rules:
 
-If C<A> inherits from C<B> and C<C> (in this order), and C<B>
-overloads C<+> by C<\&D::plus_sub>, 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>.
+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 C<fallback> key is not a subroutine, its
-inheritance is not governed by the above rules. Current implementation
-is that the value of C<fallback> in the first overloaded ancestor is
-taken, but this may be subject to change.
+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
@@ -522,6 +548,72 @@ Returns C<undef> or a reference to the method that implements C<op>.
 
 =back
 
+=head1 Overloading constants
+
+For some application Perl parser mangles constants too much.  It is possible
+to hook into this process via overload::constant() and overload::remove_constant()
+functions.
+
+These functions take a hash as an argument.  The recognized keys of this hash
+are
+
+=over 8
+
+=item integer
+
+to overload integer constants,
+
+=item float
+
+to overload floating point constants,
+
+=item binary
+
+to overload octal and hexadecimal constants,
+
+=item q
+
+to overload C<q>-quoted strings, constant pieces of C<qq>- and C<qx>-quoted
+strings and here-documents,
+
+=item qr
+
+to overload constant pieces of regular expressions.
+
+=back
+
+The corresponding values are references to functions which take three arguments:
+the first one is the I<initial> 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 C<q>- and C<qr>- constants, it is C<q> in single-quote
+context (comes from strings, regular expressions, and single-quote HERE
+documents), it is C<tr> for arguments of C<tr>/C<y> operators, 
+it is C<s> for right-hand side of C<s>-operator, and it is C<qq> otherwise.
+
+Since an expression C<"ab$cd,,"> is just a shortcut for C<'ab' . $cd . ',,'>,
+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.
+
+Note that it is probably meaningless to call the functions overload::constant()
+and overload::remove_constant() from anywhere but import() and unimport() methods.
+From these methods they may be called as
+
+       sub import {
+         shift;
+         return unless @_;
+         die "unknown import: @_" unless @_ == 1 and $_[0] eq ':constant';
+         overload::constant integer => sub {Math::BigInt->new(shift)};
+       }
+
+B<BUGS> Currently overloaded-ness of constants does not propagate 
+into C<eval '...'>.
+
 =head1 IMPLEMENTATION
 
 What follows is subject to change RSN.
@@ -546,14 +638,14 @@ 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 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.
+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
@@ -588,15 +680,17 @@ function).
 
 =head1 BUGS
 
-Because it is used for overloading, the per-package associative array
-%OVERLOAD now has a special meaning in Perl. The symbol table is
-filled with names looking like line-noise.
+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.
 
 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.
 
+Barewords are not covered by overloaded string constants.
+
 This document is confusing.
 
 =cut