From: Graham Knop Date: Thu, 18 Apr 2013 04:34:47 +0000 (-0400) Subject: make weak_ref+lazy match behavior of moose X-Git-Tag: v1.002000~29 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMoo.git;a=commitdiff_plain;h=60769550ea60d6296b1e647201378fba445ca3ed make weak_ref+lazy match behavior of moose --- diff --git a/lib/Method/Generate/Accessor.pm b/lib/Method/Generate/Accessor.pm index e5ca31d..ad9f683 100644 --- a/lib/Method/Generate/Accessor.pm +++ b/lib/Method/Generate/Accessor.pm @@ -489,11 +489,11 @@ sub _generate_core_set { sub _generate_simple_set { my ($self, $me, $name, $spec, $value) = @_; my $name_str = perlstring $name; + my $simple = $self->_generate_core_set($me, $name, $spec, $value); if ($spec->{weak_ref}) { - $value = '$preserve = '.$value; - my $simple = $self->_generate_core_set($me, $name, $spec, $value); require Scalar::Util; + my $get = $self->_generate_simple_get($me, $name, $spec); # Perl < 5.8.3 can't weaken refs to readonly vars # (e.g. string constants). This *can* be solved by: @@ -504,12 +504,10 @@ sub _generate_simple_set { # # but requires XS and is just too damn crazy # so simply throw a better exception - my $weak_simple = "my \$preserve; Scalar::Util::weaken(${simple}); no warnings 'void'; \$preserve"; + my $weak_simple = "do { Scalar::Util::weaken(${simple}); no warnings 'void'; $get }"; Moo::_Utils::lt_5_8_3() ? <<"EOC" : $weak_simple; - - my \$preserve; eval { Scalar::Util::weaken($simple); 1 } - ? do { no warnings 'void'; \$preserve; } + ? do { no warnings 'void'; $get } : do { if( \$@ =~ /Modification of a read-only value attempted/) { require Carp; @@ -523,7 +521,7 @@ sub _generate_simple_set { } EOC } else { - $self->_generate_core_set($me, $name, $spec, $value); + $simple; } } diff --git a/t/accessor-weaken.t b/t/accessor-weaken.t index 89f49fa..5da1435 100644 --- a/t/accessor-weaken.t +++ b/t/accessor-weaken.t @@ -12,24 +12,33 @@ use Test::More; use Moo; - has one => (is => 'rw', lazy => 1, weak_ref => 1, default => sub { {} }); + our $preexist = {}; + has one => (is => 'rw', lazy => 1, weak_ref => 1, default => sub { $preexist }); + has two => (is => 'rw', lazy => 1, weak_ref => 1, default => sub { {} }); } my $ref = {}; my $foo = Foo->new(one => $ref); is($foo->one, $ref, 'value present'); ok(Scalar::Util::isweak($foo->{one}), 'value weakened'); -is($foo->one($ref), $ref, 'value returned from setter'); undef $ref; ok(!defined $foo->{one}, 'weak value gone'); my $foo2 = Foo2->new; -ok(my $ref2 = $foo2->one, 'value returned'); +ok(my $ref2 = $foo2->one, 'external value returned'); +is($foo2->one, $ref2, 'value maintained'); ok(Scalar::Util::isweak($foo2->{one}), 'value weakened'); is($foo2->one($ref2), $ref2, 'value returned from setter'); undef $ref2; ok(!defined $foo->{one}, 'weak value gone'); +is($foo2->two, undef, 'weak+lazy ref not returned'); +is($foo2->{two}, undef, 'internal value not set'); +my $ref3 = {}; +is($foo2->two($ref3), $ref3, 'value returned from setter'); +undef $ref3; +ok(!defined $foo->{two}, 'weak value gone'); + # test readonly SVs sub mk_ref { \ 'yay' };