package Cat; use Moo; use MooX::Types::MooseLike::Base qw(:all); has name => ( is => 'ro', isa => Str ); 1; package Litter; use Moo; use MooX::Types::MooseLike::Base qw(:all); has cats => ( is => 'ro', isa => ArrayRef ); 1; package main; my $cat1 = Cat->new(name=>'Garfield'); my $cat2 = Cat->new(name=>'Felix'); my $litter = Litter->new(cats => [$cat1, $cat2]); for (@{$litter->cats}) { print $_->name . "\n" } #### isa => sub { my $param = shift; die "<<$param>> must be an array ref" unless ref $param eq 'ARRAY'; foreach my $element ( @{$param} ) { die "<<$element>> isn't a Cat object" unless ref $element eq 'Cat'; } } #### die "<<$element>> must have a name attribute" unless $element->can('name'); #### isa => ArrayRef[ InstanceOf['Cat'] ] #### isa => ArrayRef[ HasMethods['name'] ] #### package Cat; use Moo; use MooX::Types::MooseLike::Base 'Str'; has name => ( is => 'ro', isa => Str ); 1; package Litter; use Moo; use MooX::Types::MooseLike::Base qw( ArrayRef HasMethods ); has cats => ( is => 'ro', isa => ArrayRef [ HasMethods ['name'] ] ); 1; package main; my @cat_names = qw( Garfield Felix ); my $litter = Litter->new( cats => [ map { Cat->new( name => $_ ) } @cat_names ] ); print $_->name . "\n" for @{ $litter->cats };