I noticed a difference in the way builder methods are used between
class and instance attributes when subclassing. It is necessary to use
the + to extend a class attribute as in class_has '+attribute' => ();
in a subclass but not for an object attribute. This wasn't obvious to
me from the documentation, so took a few goes to get it right. I
wondered if it was me missing something or not understanding (quite
likely) or maybe something that should be made more obvious in the
documentation e.g. in perldoc for MooseX::ClassAttribute. In anycase
things work OK for me now, so no help specifically needed, just wanted
to provide some feedback.
Jim
The difference I found is shown below:
package FAIL::Foobar;
use Moose;
use MooseX::ClassAttribute;
use namespace::autoclean;
class_has 'class_types' => (
traits => ['Hash'],
is => 'ro',
isa => 'HashRef',
builder => '_populate_class_types',
handles => {
is_allowed_class_type => 'exists',
get_class_type => 'get',
},
);
sub _populate_class_types {
return {
type1 => 'class type one',
};
}
has 'instance_types' => (
traits => ['Hash'],
is => 'ro',
isa => 'HashRef',
builder => '_populate_instance_types',
handles => {
is_allowed_instance_type => 'exists',
get_instance_type => 'get',
},
);
sub _populate_instance_types {
return {
type1 => 'instance type one',
};
}
__PACKAGE__->meta->make_immutable;
1;
package FAIL::Foobar::FoobarSubclass;
use Moose;
use MooseX::ClassAttribute;
extends 'FAIL::Foobar';
use namespace::autoclean;
class_has '+class_types' => ();
sub _populate_class_types {
return {
type1 => 'class type one',
type2 => 'class type two',
};
}
sub _populate_instance_types {
return {
type1 => 'instance type one',
type2 => 'instance type two',
};
}
__PACKAGE__->meta->make_immutable;
1;
In a script to test:
use FAIL::Foobar;
my $foobar_obj = FAIL::Foobar->new();
$class_type = $foobar_obj->get_class_type( 'type1' );
$instance_type = $foobar_obj->get_instance_type( 'type1' );
print "$class_type\n" if $class_type;
print "$instance_type\n" if $instance_type;
use FAIL::Foobar::FoobarSubclass;
my $foobar_subclass_obj = FAIL::Foobar::FoobarSubclass->new();
$class_type = $foobar_subclass_obj->get_class_type( 'type2' );
$instance_type = $foobar_subclass_obj->get_instance_type( 'type2' );
print "$class_type\n" if $class_type;
print "$instance_type\n" if $instance_type;