<?xml version="1.0" encoding="windows-1252"?>
<node id="948730" title="Re: Moose(X) create my own Collection" created="2012-01-19 04:38:05" updated="2012-01-19 04:38:05">
<type id="11">
note</type>
<author id="757127">
tobyink</author>
<data>
<field name="doctext">
&lt;p&gt;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.&lt;/p&gt;

&lt;code&gt;
package MyCollection;
use MooseX::Role::Parameterized;

parameter type =&gt; (
  isa      =&gt; 'ClassName',
  required =&gt; 1,
);

parameter attr =&gt; (
  isa      =&gt; 'Str',
  required =&gt; 1,
);

role {
  my $p = shift;
  my ($type, $attr) = ($p-&gt;type, $p-&gt;attr);

  has $attr =&gt; (
    is =&gt; 'rw',
    isa =&gt; "HashRef[$type]",
    traits =&gt; ['Hash'],
    defaults =&gt; sub { {} }
    );

  method "summon_$attr" =&gt; sub {
    my $self = shift;
    foreach my $item (values %{ $self-&gt;$attr }) {
      $item-&gt;summon if $item-&gt;does('Summonable');
    }
  };
};

# and we'll use MooseX::Declare syntax for the rest...

role Summonable {
  requires 'name';
  method summon {
    say "Come here, ", $self-&gt;name;
  }
}

class Child with Summonable {
  has name =&gt; ( is =&gt; 'ro', isa =&gt; 'Str' );
}

class Parent {
  with MyCollection =&gt; { type =&gt; 'Child', attr =&gt; 'children' };
}

my $me = Parent-&gt;new;
$me-&gt;children-&gt;{isabel} = Child-&gt;new(name =&gt; 'Isabel');
$me-&gt;children-&gt;{elliott} = Child-&gt;new(name =&gt; 'Elliott');
$me-&gt;summon_children;
&lt;/code&gt;

&lt;p&gt;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.&lt;/p&gt;</field>
<field name="root_node">
948713</field>
<field name="parent_node">
948713</field>
</data>
</node>
