X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/3aaeec97680c6839567bb4fb292d6aa1824c6031..b3c290c26b9b9e51e5664a73d5f04cd807766b2d:/lib/overload.pm diff --git a/lib/overload.pm b/lib/overload.pm index 109b7c5..4a1912c 100644 --- a/lib/overload.pm +++ b/lib/overload.pm @@ -1,6 +1,6 @@ package overload; -our $VERSION = '1.19'; +our $VERSION = '1.26'; %ops = ( with_assign => "+ - * / % ** << >> x .", @@ -8,8 +8,8 @@ our $VERSION = '1.19'; num_comparison => "< <= > >= == !=", '3way_comparison' => "<=> cmp", str_comparison => "lt le gt ge eq ne", - binary => '& &= | |= ^ ^=', - unary => "neg ! ~", + binary => '& &= | |= ^ ^= &. &.= |. |.= ^. ^.=', + unary => "neg ! ~ ~.", mutators => '++ --', func => "atan2 cos sin exp abs log sqrt int", conversion => 'bool "" 0+ qr', @@ -30,11 +30,11 @@ sub nil {} sub OVERLOAD { $package = shift; my %arg = @_; - my ($sub, $fb); - *{$package . "::()"} = \&nil; # Make it findable via fetchmethod. + my $sub; + *{$package . "::(("} = \&nil; # Make it findable via fetchmethod. for (keys %arg) { if ($_ eq 'fallback') { - for my $sym (*{$package . "::(fallback"}) { + for my $sym (*{$package . "::()"}) { *$sym = \&nil; # Make it findable via fetchmethod. $$sym = $arg{$_}; } @@ -42,7 +42,7 @@ sub OVERLOAD { warnings::warnif("overload arg '$_' is invalid") unless $ops_seen{$_}; $sub = $arg{$_}; - if (not ref $sub and $sub !~ /::/) { + if (not ref $sub) { $ {$package . "::(" . $_} = $sub; $sub = \&nil; } @@ -62,15 +62,18 @@ sub import { sub unimport { $package = (caller())[0]; shift; + *{$package . "::(("} = \&nil; for (@_) { - delete $ {$package . "::"}{"(" . $_}; + warnings::warnif("overload arg '$_' is invalid") + unless $ops_seen{$_}; + delete $ {$package . "::"}{$_ eq 'fallback' ? '()' : "(" .$_}; } } sub Overloaded { my $package = shift; $package = ref $package if ref $package; - mycan ($package, '()'); + mycan ($package, '()') || mycan ($package, '(('); } sub ov_method { @@ -78,7 +81,7 @@ sub ov_method { return undef unless $globref; my $sub = \&{*$globref}; no overloading; - return $sub if !ref $sub or $sub != \&nil; + return $sub if $sub != \&nil; return shift->can($ {*$globref}); } @@ -249,7 +252,9 @@ illustrates the calling conventions: # * may recurse once - see table below Three arguments are passed to all subroutines specified in the -C directive (with one exception - see L). +C directive (with exceptions - see below, particularly +L). + The first of these is the operand providing the overloaded operator implementation - in this case, the object whose C method is being called. @@ -307,6 +312,12 @@ An appropriate implementation of C<--> might look like # ... sub decr { --${$_[0]}; } +If the experimental "bitwise" feature is enabled (see L), a fifth +TRUE argument is passed to subroutines handling C<&>, C<|>, C<^> and C<~>. +This indicates that the caller is expecting numeric behaviour. The fourth +argument will be C, as that position (C<$_[3]>) is reserved for use +by L. + =head3 Mathemagic, Mutators, and Copy Constructors The term 'mathemagic' describes the overloaded implementation @@ -358,8 +369,8 @@ hash C<%overload::ops>: num_comparison => '< <= > >= == !=', '3way_comparison'=> '<=> cmp', str_comparison => 'lt le gt ge eq ne', - binary => '& &= | |= ^ ^=', - unary => 'neg ! ~', + binary => '& &= | |= ^ ^= &. &.= |. |.= ^. ^.=', + unary => 'neg ! ~ ~.', mutators => '++ --', func => 'atan2 cos sin exp abs log sqrt int', conversion => 'bool "" 0+ qr', @@ -372,6 +383,7 @@ hash C<%overload::ops>: Most of the overloadable operators map one-to-one to these keys. Exceptions, including additional overloadable operations not apparent from this hash, are included in the notes which follow. +This list is subject to growth over time. A warning is issued if an attempt is made to register an operator not found above. @@ -404,7 +416,7 @@ evaluating an expression. =item * I += -= *= /= %= **= <<= >>= x= .= - &= |= ^= + &= |= ^= &.= |.= ^.= Simple assignment is not overloadable (the C<'='> key is used for the L). @@ -434,7 +446,7 @@ even if C<$a> is a scalar. =item * I + - * / % ** << >> x . - & | ^ + & | ^ &. |. ^. As described L, Perl may call methods for operators like C<+> and C<&> in the course @@ -493,9 +505,6 @@ If CE> is overloaded then the same implementation is used for both the I syntax C$varE> and I syntax C${var}E>. -B Even in list context, the iterator is currently called only -once and with scalar context. - =item * I The key C<'-X'> is used to specify a subroutine to handle all the @@ -650,9 +659,9 @@ to C<'-='> and C<'--'> above: And other assignment variations are analogous to C<'+='> and C<'-='> (and similar to C<'.='> and C<'x='> above): - operator || *= /= %= **= <<= >>= &= ^= |= - -------------------||-------------------------------- - autogenerated from || * / % ** << >> & ^ | + operator || *= /= %= **= <<= >>= &= ^= |= &.= ^.= |.= + -------------------||------------------------------------------- + autogenerated from || * / % ** << >> & ^ | &. ^. |. Note also that the copy constructor (key C<'='>) may be autogenerated, but only for objects based on scalars. @@ -668,7 +677,7 @@ expects. The minimal set is: + - * / % ** << >> x <=> cmp - & | ^ ~ + & | ^ ~ &. |. ^. ~. atan2 cos sin exp log sqrt int "" 0+ bool ~~ @@ -686,7 +695,8 @@ The specified function will be passed four parameters. The first three arguments coincide with those that would have been passed to the corresponding method if it had been defined. The fourth argument is the C key for that missing -method. +method. If the experimental "bitwise" feature is enabled (see L), +a fifth TRUE argument is passed to subroutines handling C<&>, C<|>, C<^> and C<~> to indicate that the caller is expecting numeric behaviour. For example, if C<$a> is an object blessed into a package declaring @@ -1043,10 +1053,7 @@ What follows is subject to change RSN. 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, C, new function -definitions, and changes in @ISA. However, this invalidation remains -unprocessed until the next Cing into the package. Hence if you -want to change overloading structure dynamically, you'll need an -additional (fake) Cing to update the table. +definitions, and changes in @ISA. (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 @@ -1056,24 +1063,12 @@ 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 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 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 the -packages acquire a magic during the next Cing into the -package. This magic is three-words-long for packages without -overloading, and carries the cache table if the package is overloaded. +If a package uses overload, it carries a special flag. This flag is also +set when new functions are defined or @ISA is modified. There will be a +slight speed penalty on the very first operation thereafter that supports +overloading, while the overload tables are updated. If there is no +overloading present, the flag is turned off. Thus the only speed penalty +thereafter is the checking of this flag. It is expected that arguments to methods that are not explicitly supposed to be changed are constant (but this is not enforced). @@ -1246,7 +1241,7 @@ Put this in F in your Perl library directory: This module is very unusual as overloaded modules go: it does not provide any usual overloaded operators, instead it provides an -implementation for L>. In this example the C +implementation for L>. In this example the C subroutine returns an object which encapsulates operations done over the objects: C<< symbolic->new(3) >> contains C<['n', 3]>, C<< 2 + symbolic->new(3) >> contains C<['+', 2, ['n', 3]]>. @@ -1604,16 +1599,6 @@ recognize. Did you mistype an operator? =item * -No warning is issued for invalid C keys. -Such errors are not always obvious: - - use overload "+0" => sub { ...; }, # should be "0+" - "not" => sub { ...; }; # should be "!" - -(Bug #74098) - -=item * - A pitfall when fallback is TRUE and Perl resorts to a built-in implementation of an operator is that some operators have more than one semantic, for example C<|>: @@ -1670,8 +1655,6 @@ may be optimized to =item * -Because it is used for overloading, the per-package hash -C<%OVERLOAD> now has a special meaning in Perl. The symbol table is filled with names looking like line-noise. =item * @@ -1702,6 +1685,10 @@ coincides with the current one. Barewords are not covered by overloaded string constants. +=item * + +The range operator C<..> cannot be overloaded. + =back =cut