As mentioned on #moose yesterday, I have found an inconsistency in the
documentation (I don't think this is a "bug", as the actual behaviour looks
reasonable and correct to me):

The documentation for Class::MOP::Attribute 0.98 says:

    This option can be either a method name or a subroutine reference. This
    method will be called when setting the attribute's value in the
    constructor. Unlike default and builder, the initializer is only called
    when a value is provided to the constructor. The initializer allows you
    to munge this value during object construction.

..but in fact the initializer is called at any point the attribute is set
(during construction, as well as after), as demonstrated by this simple
example:

package Foo;
use Moose;

has foo => (
    is => 'ro', isa => 'Int',
    initializer => sub {
        my ($this, $value, $setref, $attr) = @_;
        print "### in foo initializer!\n";
        $setref->(2 * $value);
    },
    default => 1,
    lazy => 1,
);

has bar => (
    is => 'ro', isa => 'Int',
    lazy => 1,
    default => sub { shift->foo + 1 },
);

sub BUILD { print "### in BUILD\n"; }

1;

perl -I. -MFoo -we'\
    my $obj = Foo->new; \
    print $obj->dump(1); \
    print $obj->bar; \
    print $obj->dump(1)'

produces the output:

### in BUILD
$VAR1 = bless( {}, 'Foo' );
### in foo initializer!
3$VAR1 = bless( {
                 'bar' => 3,
                 'foo' => 2
               }, 'Foo' );



-- 
   Show me a piano falling down a mineshaft and I'll show you A-flat minor.
            .             .            .            .             .
Karen Etheridge, ka...@etheridge.ca       GCS C+++$ USL+++$ P+++$ w--- M++
http://etheridge.ca/                      PS++ PE-- b++ DI++++ e++ h(-)

Reply via email to