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, [email protected] GCS C+++$ USL+++$ P+++$ w--- M++
http://etheridge.ca/ PS++ PE-- b++ DI++++ e++ h(-)