Zaid
Zaid

Reputation: 37156

Why isn't '|' being overloaded?

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'

Upvotes: 6

Views: 130

Answers (3)

brian d foy
brian d foy

Reputation: 132914

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.

Upvotes: 7

ikegami
ikegami

Reputation: 386706

[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

Upvotes: 4

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

Upvotes: 13

Related Questions