From: Dave Rolsky Date: Fri, 21 Mar 2008 22:13:33 +0000 (+0000) Subject: An immutable constructor called non-lazy attribute default subs twice. X-Git-Tag: 0_55~267 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=51c107ef51314c396093464df375f91a61c90610;p=gitmo%2FMoose.git An immutable constructor called non-lazy attribute default subs twice. --- diff --git a/Changes b/Changes index cbd3a1c..d2d4cbf 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,12 @@ Revision history for Perl extension Moose as well. There will be 2 releases, and then it will be removed. + * Moose::Meta::Method::Constructor + - immutable classes which had non-lazy attributes were calling + the default generating sub twice in the constructor. (bug + found by Jesse Luehrs, fixed by Dave Rolsky) + - added tests for this (Dave Rolsky) + 0.40 Fri. March 14, 2008 - I hate Pod::Coverage diff --git a/lib/Moose/Meta/Method/Constructor.pm b/lib/Moose/Meta/Method/Constructor.pm index 40f7a9a..8c8e1db 100644 --- a/lib/Moose/Meta/Method/Constructor.pm +++ b/lib/Moose/Meta/Method/Constructor.pm @@ -178,7 +178,7 @@ sub _generate_slot_initializer { ('$type_constraints[' . $index . ']'), '$val' ) if ($is_moose && $attr->has_type_constraint); - push @source => $self->_generate_slot_assignment($attr, $default, $index); + push @source => $self->_generate_slot_assignment($attr, '$val', $index); push @source => '}'; # close - wrap this to avoid my $val overrite warnings push @source => "}" if defined $attr->init_arg; diff --git a/t/300_immutable/007_immutable_default.t b/t/300_immutable/007_immutable_default.t new file mode 100644 index 0000000..bee24ef --- /dev/null +++ b/t/300_immutable/007_immutable_default.t @@ -0,0 +1,38 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 2; + +{ + package Foo; + use Moose; + + our $foo_default_called = 0; + + has foo => ( + is => 'rw', + isa => 'Str', + default => sub { use Devel::StackTrace; warn Devel::StackTrace->new;$foo_default_called++; 'foo' }, + ); + + our $bar_default_called = 0; + + has bar => ( + is => 'rw', + isa => 'Str', + lazy => 1, + default => sub { $bar_default_called++; 'bar' }, + ); + + __PACKAGE__->meta->make_immutable; +} + +my $foo = Foo->new(); + +is($Foo::foo_default_called, 1, "foo default was only called once during constructor"); + +$foo->bar(); + +is($Foo::bar_default_called, 1, "bar default was only called once when lazy attribute is accessed");