0

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.

daliaessam
  • 1,636
  • 2
  • 21
  • 43

1 Answers1

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.

tobyink
  • 13,478
  • 1
  • 23
  • 35
  • I tried this code based on your correction: `use MooseX::Declare; use MooseX::MethodAttributes; class Moosey { method moosey ($fname, $lname) : AttrMoosey AttrBoosy AttrCoosy { print "moosey called"; } }` then use Data::Dumper; my $class = Moosey->new; my $attrs = $class->meta->get_method('moosey'); print Dumper($attrs);` and I can see the attributes in the object hash dumped, is there any way to access this attributes hash direct for each method. – daliaessam Jul 12 '14 at 15:54
  • I was able to get a list of methods attributes direct using the code `my $attribute_list = $class->meta->get_method('moosey')->associated_metaclass()->_method_attribute_list; my $attribute_map = $class->meta->get_method('moosey')->associated_metaclass()->_method_attribute_map; print Dumper($attribute_list); print Dumper($attribute_map); ` The problem is they are stored by a numeric keys do not know how to get it, not by the method name. Can you help on this? – daliaessam Jul 12 '14 at 23:36