Hartmut Behrens
Hartmut Behrens

Reputation: 175

Set::Object with type constraint checking

I am trying to extend Set::Object in order to allow type constraint checking when inserting objects. My class so far looks like this:

package My::Set::Object;

use strict;
use warnings;

use Moose;
use MooseX::NonMoose;
extends 'Set::Object';

has type => (is => 'ro', isa => 'Str', required => 1);

before [ qw(insert invert intersection union) ] => sub {
my ($self,$list) = @_;

for (@$list) {
    confess "Only ",$self->type," objects are allowed " unless $_->does($self->type);
}
};

no Moose;
__PACKAGE__->meta->make_immutable;

Unfortunately, it appears that the construction arguments are passed through to Set::Object as well when i do the following example object construction

my $set = My::Set::Object->new(type => 'Foo::Bar');

After printing out the contents of set, i find that "type" and "Foo::Bar" are members of the set.

How can i fix this? Or is there perhaps an easier way of doing this?

Upvotes: 2

Views: 256

Answers (1)

Oesor
Oesor

Reputation: 6642

Here, as an actual answer. I usually code along these lines and should do what you need. Warning: I haven't tested this code, it may not even compile, but it should get you on the right track. The only real difference with this vs subclassing is ->ISA on your My::Set::Object objects is not going to be true when checking for 'Set::Object'.

package My::Set::Object;

use strict;
use warnings;

use Moose;
use Set::Object;

my @methods = qw/insert includes has contains invert intersection union/; # etc etc.

has type => (is => 'ro', isa => 'Str', required => 1);
has _so => (is => 'ro', isa => 'Set::Object', handles => \@methods, lazy_build => 1);

before [ qw(insert invert intersection union) ] => sub {
  my ($self,$list) = @_;

  for (@$list) {
    confess "Only ",$self->type," objects are allowed " unless $_->does($self->type);
  }
};

sub _build__so {
  return Set::Object->new()
}
no Moose;
__PACKAGE__->meta->make_immutable;

Upvotes: 6

Related Questions