package overload;
-our $VERSION = '1.00';
-
-$overload::hint_bits = 0x20000;
+our $VERSION = '1.06';
sub nil {}
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;
sub AddrRef {
my $package = ref $_[0];
return "$_[0]" unless $package;
- bless $_[0], overload::Fake; # Non-overloaded package
- my $str = "$_[0]";
- bless $_[0], $package; # Back
- $package . substr $str, index $str, '=';
-}
-sub StrVal {
- (OverloadedStringify($_[0]) or ref($_[0]) eq 'Regexp') ?
- (AddrRef(shift)) :
- "$_[0]";
+ 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;
+
+ my $mro = mro::get_linear_isa($package);
+ foreach my $p (@$mro) {
+ my $fqmeth = $p . q{::} . $meth;
+ return \*{$fqmeth} if defined &{$fqmeth};
}
+
return undef;
}
%constants = (
- 'integer' => 0x1000,
- 'float' => 0x2000,
- 'binary' => 0x4000,
- 'q' => 0x8000,
- 'qr' => 0x10000,
+ 'integer' => 0x1000, # HINT_NEW_INTEGER
+ 'float' => 0x2000, # HINT_NEW_FLOAT
+ 'binary' => 0x4000, # HINT_NEW_BINARY
+ 'q' => 0x8000, # HINT_NEW_STRING
+ 'qr' => 0x10000, # HINT_NEW_RE
);
%ops = ( with_assign => "+ - * / % ** << >> x .",
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",
}
else {
$^H{$_[0]} = $_[1];
- $^H |= $constants{$_[0]} | $overload::hint_bits;
+ $^H |= $constants{$_[0]};
}
shift, shift;
}
=head1 NAME
-overload - Package for overloading perl operations
+overload - Package for overloading Perl operations
=head1 SYNOPSIS
=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>
"++", "--",
=item * I<Special>
- "nomethod", "fallback", "=",
+ "nomethod", "fallback", "=", "~~",
see L<SPECIAL SYMBOLS FOR C<use overload>>.
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',
B<Note.> C<"fallback"> inheritance via @ISA is not carved in stone
yet, see L<"Inheritance and overloading">.
+=head2 Smart Match
+
+The key C<"~~"> allows you to override the smart matching used by
+the switch construct. See L<feature>.
+
=head2 Copy Constructor
The value for C<"="> is a reference to a function with three
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
=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
+=head1 Minimal set of overloaded operations
+
+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. See L<MAGIC AUTOGENERATION> above. The minimal set is:
+
+ + - * / % ** << >> x
+ <=> cmp
+ & | ^ ~
+ atan2 cos sin exp log sqrt int
+
+Additionally, you need to define at least one of string, boolean or
+numeric conversions because any one can be used to emulate the others.
+The string conversion can also be used to emulate concatenation.
+
=head1 Losing overloading
The restriction for the comparison operation is that even if, for example,
=item overload::StrVal(arg)
-Gives string value of C<arg> as in absence of stringify overloading.
+Gives string value of C<arg> as in 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
+C<Scalar::Util::refaddr()>, which is faster.
=item overload::Overloaded(arg)
=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.
+For some applications, the Perl parser mangles constants too much.
+It is possible to hook into this process via C<overload::constant()>
+and C<overload::remove_constant()> functions.
These functions take a hash as an argument. The recognized keys of this hash
-are
+are:
=over 8
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.
=head2 Two-face references
Suppose you want to create an object which is accessible as both an
-array reference and a hash reference, similar to the
-L<pseudo-hash|perlref/"Pseudo-hashes: Using an array as a hash">
-builtin Perl type. Let's make it better than a pseudo-hash by
-allowing index 0 to be treated as a normal element.
+array reference and a hash reference.
package two_refs;
use overload '%{}' => \&gethash, '@{}' => sub { $ {shift()} };
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