问题
I am trying to use Moose, MooseX::Declare, and MooseX::MethodAttributes to be able to use class
and method
keywords instead of package
and sub
and at the same time get the methods attributes, so I need this form of packages and methods:
class Moosey {
method connect ($user, $pass) : Action GET {...}
}
If I use sub
keyword it will work with attributes but of course no method signatures, If I use method
keyword, it will hang the script if I use method attributes.
Below is the code I am trying:
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";
My question is does these Moose modules allows me to do this.
回答1:
MooseX::Method::Signatures (which is what MooseX::Declare uses to handle methods) does support attributes, but they need to appear after the signature, not before it:
method foo :MyAttr ($arg1, $arg2) { # NO
...;
}
method foo ($arg1, $arg2) :MyAttr { # YES
...;
}
However, it does not seem to work with MooseX::MethodAttributes because they both try to override Moose's default metaclass for methods.
I would like to be able to say "use Moops instead". But that seems to fail for a different reason. A workaround is to declare the allowed attributes in 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 provides nice introspection for method signatures:
my @params = Moosey->meta->get_method("moosey2")->signature->positional_params;
say $_->name for @params; # says '$name'
# says '$email'
But it doesn't provide much in the way for attributes. (Yet.)
TL;DR: no.
来源:https://stackoverflow.com/questions/24707056/perl-moosexdeclare-with-method-attributes-moosexmethodattributes