I've got a pretty good implementation of multimethods on CPAN. I'm biased, but I think it's the best underlying implementation, though I've done almost zero work on making the syntax nice.
use strict;
use warnings;
use experimental qw( signatures builtin );
use feature qw( say );
use builtin qw( true false );
use Sub::MultiMethod -all, -lexical;
use Types::Common -types, -lexical;
package Foo { use Class::Tiny };
package Bar { use Class::Tiny };
multifunction frobnicate => (
positional => [ InstanceOf['Foo'] ],
code => sub ( $o ) { return 'It was a Foo.' },
);
multifunction frobnicate => (
positional => [ InstanceOf['Bar'] ],
code => sub ( $o ) { return 'It was a Bar.' },
);
multifunction frobnicate => (
positional => [ HashRef, ArrayRef ],
code => sub ( $h, $a ) { return 'They were a hashref and array
+ref.' },
);
multifunction frobnicate => (
named => [ message => Str, truth => Bool ],
code => sub ( $arg ) { $arg->truth ? $arg->message : 'Truth wa
+s false' },
);
say frobnicate( Foo->new );
say frobnicate( Bar->new );
say frobnicate( {}, [] );
say frobnicate( message => "This will be seen", truth => true
+ );
say frobnicate( message => "This will NOT be seen", truth => false
+ );
say frobnicate( { message => "This will be seen", truth => true }
+ );
say frobnicate( { message => "This will NOT be seen", truth => false }
+ );
say frobnicate( [], undef, 123 ); # dies; no implementation available
|