I need multemethod dispatch with Moose objects. I'm doing this with Class::Multimethods::Pure. I chose this instead of MooseX::MultiMethods because it depends on MooseX::Method::Signatures which can't install on my system because it fails its tests. I don't mind if you have an alternative approach to suggest.
The following works fine with types and subtypes:
package Foo::Type;
use Moose;
package Foo::SubType;
use Moose;
extends 'Foo::Type';
package main;
use Class::Multimethods::Pure;
multi hello => ('Foo::Type') => sub {
my ( $foo ) = @_;
print $foo;
};
hello( Foo::SubType->new );
But the scenario I now need to handle is where the declared type is actually a Moose Role:
package Foo::Role;
use Moose::Role;
package Foo::Type;
use Moose;
with 'Foo::Role';
package main;
use Class::Multimethods::Pure;
multi hello => ('Foo') => sub {
my ( $foo ) = @_;
print $foo;
};
hello( Foo::Type->new );
But this can't recognise the role:
No method found for args (Foo::Type=HASH(0x22ac854))
The documentation says it can be extended in various ways, including adding Perl 6-ish roles. But it's a little sketchy for me and I'm looking for a more detailed example. Has anyone tried this?
My solution was to convert the roles to abstract base classes using MooseX::ABC. In this way, they could be recognised as a class type.
On a side note, I managed to get MooseX::MultiMethods working on another system. It does work with roles, but it can't figure out which to use if we define a multimethod that takes the class and another multimethod that takes the role. Incidentally, MooseX::ABC resolved this issue also since it gave me a hierarchical structure which the roles did not really have.
package Foo::Role;
use Moose::Role;
package Foo::Type;
use Moose;
with 'Foo::Role';
package Merger;
use Moose;
use MooseX::MultiMethods;
multi method hello (Foo::Role $foo) {
print 'Foo::Role: '.$foo;
}
multi method hello (Foo::Type $foo) {
print 'Foo::Type: '.$foo;
}
package main;
my $merger = Merger->new;
my $f = Foo::Type->new;
$merger->hello( $f );
# Ambiguous match for multi method hello: (Foo::Role $foo), (Foo::Type $foo)
# with value [ Merger{ }, Foo::Type{ } ]