我正在尝试使用Moose,MooseX::Declare和MooseX::MethodAttributes来使用class
和method
关键字代替package
和sub
并同时获取方法属性,所以我需要这种形式的包和方法:
class Moosey {
method connect ($user, $pass) : Action GET {...}
}
如果我使用sub
关键字,它将使用属性,但当然没有方法签名,如果我使用method
关键字,如果我使用方法属性,它将挂起脚本。
以下是我正在尝试的代码:
package Moosey;
use Moose;
use MooseX::Declare;
use MooseX::MethodAttributes;
class Moosey {
# this works fine
sub moosey : Action { print "moosey called"; }
# this line hangs the script
# Error: Can't locate object method "attributes" via package "MooseX::Method::Signatures::Meta::Method"
#method moosey : Action { print "moosey called"; }
# this also does not work
#method moosey : Get ($name, $email) { print "moosey called"; }
}
1;
my $class = Moosey->new;
my $attrs = $class->meta->get_method('moosey')->attributes;
print "@$attrs";
我的问题是这些Moose模块是否允许我这样做。
答案 0 :(得分:1)
MooseX :: Method :: Signatures(这是MooseX :: Declare用来处理方法)确实支持属性,但是它们需要在签名后出现,而不是在它之前:
method foo :MyAttr ($arg1, $arg2) { # NO
...;
}
method foo ($arg1, $arg2) :MyAttr { # YES
...;
}
然而,似乎无法与MooseX :: MethodAttributes一起工作因为它们都试图覆盖Moose的方法的默认元类。
我希望能够说“使用Moops代替”。但这似乎因为一个不同的原因而失败。解决方法是在UNIVERSAL
...
use Moops;
package UNIVERSAL {
use Sub::Talisman qw( Action Get );
}
class Moosey using Moose {
method moosey1 :Action(FOO,BAR,BAZ) {
say "moosey1 called";
}
method moosey2 (Str $name = "Bob", Str $email?) :Get {
say "moosey2 called $name";
}
}
Moops为方法签名提供了很好的内省:
my @params = Moosey->meta->get_method("moosey2")->signature->positional_params;
say $_->name for @params; # says '$name'
# says '$email'
但它并没有为属性提供太多帮助。 (然而)
TL; DR:没有。