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

Moose(X) create my own Collection

by ragnaev (Initiate)
on Jan 19, 2012 at 08:02 UTC ( #948713=perlquestion: print w/replies, xml ) Need Help??
ragnaev has asked for the wisdom of the Perl Monks concerning the following question:

Hi PerlMonks, I am a beginner in Moose(X) trying to create a collection of some predefined my types.
use MooseX::Declare class MyCollection { has 'items' => ( is => 'rw', isa => 'HashRef[Object]', traits => ['Hash'], defaults => sub { {} } ) some..methods } use MooseX::Declare; class Child { has 'name' => ( is => 'rw', isa => 'Str' ); some..methods } use MooseX::Declare; use MyCollection class Parent { has 'children => ( is => 'rw', isa => 'MyCollection' ) some..methods }
So I would like to have in class Parent->children the Collection of child. How to specify that 'children' => isa 'MyCollection[Child]' I try to do so but with no luck. Got and error. Then I try to create a subtype look like
subtype 'MyChildrenCollection' => as 'Collection', where => { $_->isa('Child') }
and use in
has 'children' => (is => 'rw', 'isa' => 'MyChildrenCollection'
but again no luck. Please dear PerlMontks give me your advice Thanks in advance

Replies are listed 'Best First'.
Re: Moose(X) create my own Collection
by tobyink (Abbot) on Jan 19, 2012 at 09:38 UTC

    You don't want to define MyCollection as a class. Define it as a parameterised role instead. IIRC, there is some MooseX::Declare syntactic sugar for parameterised roles, but I can't remember exactly how it goes, and it's undocumented.

    package MyCollection; use MooseX::Role::Parameterized; parameter type => ( isa => 'ClassName', required => 1, ); parameter attr => ( isa => 'Str', required => 1, ); role { my $p = shift; my ($type, $attr) = ($p->type, $p->attr); has $attr => ( is => 'rw', isa => "HashRef[$type]", traits => ['Hash'], defaults => sub { {} } ); method "summon_$attr" => sub { my $self = shift; foreach my $item (values %{ $self->$attr }) { $item->summon if $item->does('Summonable'); } }; }; # and we'll use MooseX::Declare syntax for the rest... role Summonable { requires 'name'; method summon { say "Come here, ", $self->name; } } class Child with Summonable { has name => ( is => 'ro', isa => 'Str' ); } class Parent { with MyCollection => { type => 'Child', attr => 'children' }; } my $me = Parent->new; $me->children->{isabel} = Child->new(name => 'Isabel'); $me->children->{elliott} = Child->new(name => 'Elliott'); $me->summon_children;

    The above is untested, and probably has some syntax errors lurking somewhere, but it should give you an idea of how it can be done.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2016-10-01 21:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?






    Results (7 votes). Check out past polls.