Why isn't '|' being overloaded?

≯℡__Kan透↙ 提交于 2020-05-14 19:10:25

问题


The following code does not work as expected. What am I missing?

use strict;
use warnings;
use overload '|' => sub { 1 / ( 1 / $_[0] + 1 / $_[1] ) };

print( 5 | 5 ); # Prints '5' instead of '2.5'

回答1:


overload works only on blessed references ("objects").

package MyNumber;
use strict;
use warnings;
use overload '|' => sub { 1 / ( 1 / +$_[0] + 1 / +$_[1] ) },
            '0+' => sub { $_[0]->{value} }, # Cast to number
            fallback => 1;                  # Allow fallback conversions

# "Constructor", bless number as MyNumber
sub num {
    my $self = { value => $_[0] };  # can be any reference
    return bless $self, "MyNumber";
}

print(num(5) | num(5));


my $a = num(5);
print ($a | 5); # This works too



回答2:


Overloading works on objects, like so:

use v5.10;

package Number {
    use overload 
        '|' => sub { 1 / ( 1 / ${$_[0]} + 1 / ${$_[1]} ) },
        fallback => 1
        ;

    sub new {
        my( $class, $arg ) = @_;
        bless \ $arg, $class;
        }
    }   

my $n = Number->new( 5 );
my $m = Number->new( 5 );


say( $n | $m );

There are lots of things to pay attention to, though, since Perl 5 doesn't do multi-method dispatch. In your subroutine you have to figure out the second argument and do the right thing yourself. That can get complicated. I'd much rather use normal methods for this.




回答3:


[The question has already been answered. This is a comment that doesn't fit in the comment box.]

Can be done using autoboxing:

use strict;
use warnings;

use overload '|' => sub { 1 / ( 1 / ${$_[0]} + 1 / ${$_[1]} ) };

BEGIN { overload::constant integer => sub { my ($n) = @_; bless(\$n) }; }

print( 5 | 5, "\n" );  # 2.5


来源:https://stackoverflow.com/questions/23890713/why-isnt-being-overloaded

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!