tags:

views:

114

answers:

4

Can I use isa in Moose with a regex as a parameter ? If not possible can I achieve the same thing with someothing other than ->isa ?

ok, having the following types Animal::Giraffe , Animal::Carnivore::Crocodile , I want to do ->isa(/^Animal::/), can I do that ? if I can't, what can I use to reach the desired effect ?

+1  A: 

I think this should do it.

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

my $animal = Moose::Meta::TypeConstraint->new(
    constraint => sub { $_[0] =~ /^Animal::/}
);

has animal => (is => 'rw', isa => $animal);

ETA: I agree with jrockway though: unless you have a convincing reason otherwise, you should just use inheritance.

Leon Timmermans
Nit-picky point of correction, `does` checks for role composition rather than inheritance. I also agree that checking for role composition is preferable :) Anal-retentive moment over.
perigrin
+3  A: 

Leon Timmermans' answer was close to what I'd suggest though I'd use the sugar from Moose::Util::TypeConstraints

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

subtype Animal => as Object => where { blessed $_ =~ /^Animal::/ };

has animal => ( is => 'rw', isa => 'Animal' );
perigrin
+5  A: 

These related types should all "do" the same role, Animal. Then you can write:

has 'animal' => (
    is       => 'ro',
    does     => 'Animal',
    required => 1,
);

Now you have something much more reliable than a regex to ensure the consistency of your program.

jrockway
+2  A: 

Extending perigrin's answer so that it will work if the class has an Animal::* anywhere in its superclasses, and not only in its immediate class name (for example if Helper::Monkey isa Animal::Monkey):

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

subtype Animal => 
  as Object =>
  where { grep /^Animal::/, $_->meta->linearized_isa };

has animal => ( is => 'rw', isa => 'Animal' );

I think jrockway's suggestion to use a role instead has a lot of merit, but if you want to go this way instead, you might as well cover all of the bases.

hobbs