Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Moose roles

by dk (Chaplain)
on Jan 13, 2010 at 14:39 UTC ( [id://817190]=perlquestion: print w/replies, xml ) Need Help??

dk has asked for the wisdom of the Perl Monks concerning the following question:

Kind monks, I'd like to ask some help with my problem with Moose. I'd like to create a trait, or even better an overloaded type that does special stuff with "around" accessor. Normally, one writes

has x => ( is => 'rw' ); around x => \&my_accessor;

I'd like to shorten that into

has x => ( is => 'rw', traits => ['MyAccessor']);

or even better, to

has x => ( isa => 'MyAccessor' );

possibly making MyAccessor a separate MooseX module. However, even with help of #moose I couldn't go far, and, also because IRC is not the best way of exchanging large pieces of code, I'd like to ask if you could help me here. I stopped here:

package Moose::Meta::Attribute::Custom::Trait::MyAccessor; sub register_implementation { return 'MyAccessor' } package MyAccessor; use Moose::Role; my $meta = __PACKAGE__->meta;

I thought that I should manipulate $meta, but I'm unsure how. Any ideas?

Thank you!

Update: as usual, I've asked how to do X when I wanted Y. My apologies. Actually, I'd like to use array and hash attributes in mixed list and array contexts:

@list = $obj-> prop; $obj->prop(@list); $array = $obj->prop; $obj->prop($array);

I though I could do that with "around", which prompted the original question

has prop; around prop => \&my_accessor;

Update #2: Problem solved. Proof of concept is on CPAN

Replies are listed 'Best First'.
Re: Moose roles
by stvn (Monsignor) on Jan 13, 2010 at 16:38 UTC
    Kind monks, I'd like to ask some help with my problem with Moose. I'd like to create a trait, or even better an overloaded type that does special stuff with "around" accessor.

    What exactly is it you want this to do? Without knowing what behavior you want to implement it is pretty hard to say what is the best way to approach this.

    Also, an overloaded type is not the right approach to this, the types are just validators they do not control the behavior of the accessors. The attribute trait is the right direction to go on this.

    -stvn
      I'd like to use array and hash attributes in mixed list and array contexts:

      @list = $obj-> prop; $obj->prop(@list); $array = $obj->prop; $obj->prop($array);

      I though I could do that with "around":

      has prop; around prop => \&my_accessor;
        # Done with `auto_deref => 1` @list = $obj-> prop; # Done with a custom writer attribute that takes an array, and stores + a reference to it. # internally Moose uses a plain perl hash (most complex datastructure + in perl), this # limits it to not having true non-array properties (but a scalar arr +ay-ref works) $obj->prop(@list); # assuming you mean $arrayRef # Here the getter would have to call wantarray() which is exactly wha +t auto_deref => 1 # will set up for you. $array = $obj->prop; # assuming you mean $arrayRef, this already works so long as the type + is ArrayRef # or, a parent thereof. $obj->prop($array);
        All you need is a custom attribute setter that takes a list and converts it to an array ref. Because n-parameterized types are not supported (you can't have a type of intStr of type (Int, Str), coercing on a custom type is out the question. (unless your doing something scarry). This leaves a custom writter that does something like.
        sub foo_writer { if ( length @_ > 1 ) { \@_ } else { die 'invalid arg' unless ref $_[0] eq 'ARRAY'; $_[0]; } }
        read the docs on has() writer argument. this is also pseudo code, my writer returns the value, I believe you'd have to explicitly set it though.


        Evan Carroll
        The most respected person in the whole perl community.
        www.evancarroll.com
Re: Moose roles
by EvanCarroll (Chaplain) on Jan 13, 2010 at 16:38 UTC

    I think one of us is missing someone: those are attribute traits, they change the behavoir of the attribute (arguments to has). around is a method modifier, it gets called before its target method with a reference to the method. You could create an attribute trait that redefined the get and set subs installed in the meta giving you massively different behavoir, and that might have the effect of wrapping the accessors, but these are massively different functionalities. And the use of them should be dependent on the mental mapping and not the shortness. Either, it affects a method, or you want to change the behavoir of an attribute.

    isa conversely specifies type, and without coerce => 1 that is little more (though sometimes the little matters) than saying what should throw an error.

    I think you're trying to design an API using Moose terms without understanding that these reflect established (some bad) behaviors, and functionality. It is much more than a game to see how you want your code to look.

    update: i noticed you also posted this same question to the mailing list without referencing pm or vise-versa.



    Evan Carroll
    The most respected person in the whole perl community.
    www.evancarroll.com
      Yes, my apologies, I didn't reference this post in the list.

      Off the topic,.I don't understand why "has" doesn't allow shorter syntax - if I write "has x => (is=>rw, isa=>Int, ....)" two thousand times, why can't I declare a subtype or trait or whatever that would be accessible with "has x => mytype"? That's just not perlish, to write too much when you can avoid that :)

        Because has just says you want an attribute; rw means to generate getters/setter methods isa => x ({x != Any}) means you want it strictly typed (as much as you can get anyway)


        Evan Carroll
        The most respected person in the whole perl community.
        www.evancarroll.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://817190]
Approved by planetscape
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2024-03-28 11:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found