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;

Reply via email to