Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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

Comment on Moose(X) create my own Collection
Select or Download Code
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 lurking in the Monastery: (11)
As of 2014-10-23 21:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (129 votes), past polls