use warnings;
use strict;
#use experimental qw( signatures );
{ package My::A;
use overload '-' => \−
# sub minus($x, $y, $swap) { ############ Replaced by next line ##
sub minus { my($x, $y, $swap) = (shift, shift, shift);
return ref($x)->new(
($y->isa('My::B') ? $x->[0] - $y->{value}
: ($x->[0] - $y->[0])
) * (1, -1)[$swap]
)
}
# sub new($class, $value) { ############ Replaced by next line ##
sub new { my($class, $value) = (shift, shift);
bless [$value], $class
}
# We can change My::B outside of B, in fact.
eval q{ package My::B;
my $m = My::B->can('minus') or die 'My::B not loaded';
use overload "-" => sub { my($x, $y, $s) = (shift, shift, shift);
return $y->isa('My::A') ? $y->minus($x, 1) : $m->($x, $y, $s)
}
};
}
{ package My::B; # Can't be changed!
use overload '-' => \−
# sub minus($x, $y, $swap) { ############ Replaced by next line ##
sub minus { my($x, $y, $swap) = (shift, shift, shift);
my $subtr = $x->{value} - $y->{value};
return ref($x)->new($swap ? -$subtr : $subtr)
}
# sub new($class, $value) { ############ Replaced by next line ##
sub new { my($class, $value) = (shift, shift);
bless {value => $value}, $class
}
}
my $a0 = 'My::A'->new(16);
my $a1 = 'My::A'->new(6);
my $b0 = 'My::B'->new(16);
my $b1 = 'My::B'->new(6);
use Data::Dumper;
print Dumper A => $a0 - $a1;
print Dumper B => $a0 - $b1;
print Dumper C => $b0 - $b1;
print Dumper D => $b0 - $a1;
print Dumper AA => $a1 - $a0;
print Dumper BB => $b1 - $a0;
print Dumper CC => $b1 - $b0;
print Dumper DD => $a1 - $b0;
####
>perldoc -f can
No documentation for perl function 'can' found
####
This feature is available from Perl 5.31.6 onwards when enabled by "use
feature 'isa'". This feature is enabled automatically by a "use v5.36"
(or higher) declaration in the current scope.