如何扩展Class :: Multimethods :: Pure来识别Moose角色?

时间:2012-03-21 06:52:19

标签: perl moose multimethod

我需要使用Moose对象进行multemethod调度。我是用Class::Multimethods::Pure做的。我之所以选择此而不是MooseX::MultiMethods,因为它取决于MooseX::Method::Signatures,因为它无法通过测试而无法安装在我的系统上。我不介意你是否有另一种建议方法。

以下适用于类型和子类型:

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 );

但我现在需要处理的场景是声明的类型实际上是Moose角色:

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 );

但这无法识别角色:

No method found for args (Foo::Type=HASH(0x22ac854))

documentation表示可以通过各种方式进行扩展,包括添加Perl 6-ish角色。但这对我来说有点粗略,我正在寻找一个更详细的例子。有人试过吗?

1 个答案:

答案 0 :(得分:0)

我的解决方案是使用MooseX::ABC将角色转换为抽象基类。通过这种方式,它们可以被识别为类类型。

另一方面,我设法让MooseX :: MultiMethods在另一个系统上工作。它确实适用于角色,但如果我们定义一个采用类的多方法和另一个扮演角色的多方法,它就无法弄清楚要使用哪个。顺便说一句,MooseX :: ABC也解决了这个问题,因为它给了我一个角色结构,而角色并没有真正拥有。

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{  } ]