Differences in builder class and instance behaviour

[email protected] ("Jim Mozley (greenboots.org)")
Newsgroups perl.moose
Message-ID <CAAsq+jtqHq0OxqJd9ZF_spGQfnz1Rh02qtW4XTGLEghWRgo=qw@mail.gmail.com>
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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.