Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

declaration order of attributes in Moose

by morgon (Deacon)
on Apr 13, 2009 at 20:37 UTC ( #757274=perlquestion: print w/ replies, xml ) Need Help??
morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I wonder if there is an "official" way to retrieve the order in which attributes have been declared in a Moose-based class, e.g. when I have a class defined as

package Hubba; use Moose; has abba => (is => 'rw'); has zappa => (is => 'rw');
I want to have a way to retrive (via the meta-class) the information that abba has been declared before zappa.

In fact I can get to what I want by doing this:

my $h = Hubba->new( abba => 1, zappa => 2); my @atts = $h->meta->{_meta_instance}->{slots};
Then @atts contains the list "abba", "zappa".

But of course this looks a bit hacky...

And please don't ask me what I need it for - at the moment I am just learing what you can and cannot do with Moose.

Many thanks!

Comment on declaration order of attributes in Moose
Select or Download Code
Re: declaration order of attributes in Moose
by kyle (Abbot) on Apr 13, 2009 at 21:10 UTC

    Your hacky way of getting what you want doesn't work with the Moose I'm using (0.51). Here I can get a list of slots this way:

    my @atts = $h->meta->get_meta_instance->get_all_slots;

    That gives the list in no particular order, however.

    Looking at the object with Data::Dumper, I don't see any place that stores an ordered list of attributes. I suspect that your "working" code is working by coincidence. Try it with this package:

    package Hubba; use Moose; foreach my $name ( 'a' .. 'z' ) { has $name => ( is => 'rw' ); }

    I think the only way you're going to get what you want is to look into Moose's definition of has and patch it so that it tracks the information you want to have.

    You've asked us not to question your motives here, so I won't, but any code that requires this information probably has a design problem of some kind. I recommend finding another solution to whatever your real problem is.

Re: declaration order of attributes in Moose
by stvn (Monsignor) on Apr 14, 2009 at 00:23 UTC
    I wonder if there is an "official" way to retrieve the order in which attributes have been declared in a Moose-based class

    No, there is no official way, Moose stores the attributes in a hash, so they are essentially unordered.

    Depending on your needs, there are a number of ways to go about this. The simplest is to make a custom meta-attribute that can take an "order" field. There is a recipe for custom meta-attributes and meta-attribute traits in the Moose::Cookbook and the Moose::Manual also touches on this topic a little too. If you did this then you could write your code like so:

    package Hubba; use Moose; has abba => (metaclass => 'MyOrderedCustomAttribute', is => 'rw', orde +r => 1); has zappa => (metaclass => 'MyOrderedCustomAttribute', is => 'rw', ord +er => 2);
    Then you could simply get all the attribute using Hubba->meta->get_all_attributes and sort them by their order field. The obvious drawback here is that you have to specify the ordering yourself. Of course with a little trickery and some class level data in your custom meta-attribute you could probably avoid this.

    Another (slightly more complex) way would be to have a custom meta-class that simply wrapped the add_attribute method and kept an ordered list of attributes to be retrieved later. The Moose::Cookbook and Moose::Manual also touch on custom meta-classes as well.

    One thing for sure though, you should not reach into private attributes (like $h->meta->{_meta_instance}) to get this kind of data, because they are private and therefore should not be relied upon for code outside of the core Moose.

    You might also want to try asking this on the Moose mailing list (moose@perl.org) or on the Moose IRC channel (#moose@irc.perl.org) as you are certainly not the first person who has wanted to do this and other people may have already working solutions that you can use.

    -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://757274]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2014-12-26 21:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls