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.