Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://948713]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2018-07-23 04:26 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (459 votes). Check out past polls.