1

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?

stevenl
  • 6,736
  • 26
  • 33

1 Answers1

0

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{  } ]
stevenl
  • 6,736
  • 26
  • 33