Moose attributes - accepting multiple modules with common parent

91 views Asked by At

Need do something like the next (and more):

my $val1 = My::Module::Type1->new(...);
my $val2 = My::Module::Type2->new(...);

my $some = Some->new( val => [$val1, $val2] );

How to define the $val in a Some package (Moose based)? So,

package Some;
use Moose;
has 'val' => (
    isa => 'ArrayRef[My::Module::__ANYTHING__HERE__]', # <-- here is the problem
);

The problem is than now have only My::Module::Type1 but how to construct the Some->val for accepting any future My::Module::_something_?

My best idea is

use Moose;
use Moose::Util::TypeConstraints;
usa Scalar::Util qw( blessed );

subtype MySubModule,
    as Object => where {
         blessed $_ =~ /^My::Module/
    },
    message { "Need My::Module class" };

has val => ( is => 'rw', isa => 'ArrayRef[MySubModule]' );

But i don't think than this is a best way, because what if someone makes Your::Module what will be a subclass of My::Module?

Can anybody advice me something more correct solution?

(Probably will need somewhat incorporate roles, (or traits), but (honestly) - still never used any Role - and haven't idea how to use them.. ;( )

I hope the above is understandable - unfortunately my english is similary bad as my perl.. ;(

1

There are 1 answers

0
tobyink On BEST ANSWER

Use a class type constraint. It respects inheritance...

use Moose;
use Moose::Util::TypeConstraints;

class_type 'MyModule', { class => 'My::Module' };

has val => ( is => 'rw', isa => 'ArrayRef[MyModule]' );

Or better (though bear in mind I'm biased)...

use Moose;
use Types::Standard -types;

has val => (is => 'rw', isa => ArrayRef[InstanceOf['My::Module']]);