xxxxxxx
xxxxxxx

Reputation: 5167

Can I pass a regex to isa() with Moose-based objects?

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 ?

Upvotes: 4

Views: 734

Answers (4)

Leon Timmermans
Leon Timmermans

Reputation: 30225

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.

Upvotes: 0

hobbs
hobbs

Reputation: 240010

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.

Upvotes: 4

jrockway
jrockway

Reputation: 42674

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.

Upvotes: 8

perigrin
perigrin

Reputation: 4433

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' );

Upvotes: 4

Related Questions