From: Matt S Trout Date: Mon, 14 May 2012 07:33:07 +0000 (+0000) Subject: a weakened value should still be returned on set (fixes lazy + weak_ref) X-Git-Tag: v0.091005~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6998abed26a68b7adc6254bb6e1900623b2ac903;p=gitmo%2FMoo.git a weakened value should still be returned on set (fixes lazy + weak_ref) --- diff --git a/Changes b/Changes index b2c2c13..215507d 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,4 @@ + - a weakened value should still be returned on set (fixes lazy + weak_ref) - add an explicit return to all exported subs so people don't accidentally rely on the return value diff --git a/lib/Method/Generate/Accessor.pm b/lib/Method/Generate/Accessor.pm index b01ab04..05d4764 100644 --- a/lib/Method/Generate/Accessor.pm +++ b/lib/Method/Generate/Accessor.pm @@ -399,9 +399,10 @@ 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; # Perl < 5.8.3 can't weaken refs to readonly vars @@ -413,8 +414,10 @@ sub _generate_simple_set { # # but requires XS and is just too damn crazy # so simply throw a better exception - Moo::_Utils::lt_5_8_3() ? <<"EOC" : "Scalar::Util::weaken(${simple})"; + my $weak_simple = "my \$preserve; Scalar::Util::weaken(${simple})"; + Moo::_Utils::lt_5_8_3() ? <<"EOC" : $weak_simple; + my \$preserve; eval { Scalar::Util::weaken($simple); 1 } or do { if( \$@ =~ /Modification of a read-only value attempted/) { require Carp; @@ -428,7 +431,7 @@ sub _generate_simple_set { }; EOC } else { - $simple; + $self->_generate_core_set($me, $name, $spec, $value); } } diff --git a/t/accessor-weaken.t b/t/accessor-weaken.t index d390c27..ec5b069 100644 --- a/t/accessor-weaken.t +++ b/t/accessor-weaken.t @@ -7,6 +7,12 @@ use Test::More; use Moo; has one => (is => 'ro', weak_ref => 1); + + package Foo2; + + use Moo; + + has one => (is => 'lazy', weak_ref => 1, default => sub { {} }); } my $ref = {}; @@ -14,7 +20,13 @@ my $foo = Foo->new(one => $ref); is($foo->one, $ref, 'value present'); ok(Scalar::Util::isweak($foo->{one}), 'value weakened'); undef $ref; -ok (!defined $foo->{one}, 'weak value gone'); +ok(!defined $foo->{one}, 'weak value gone'); + +my $foo2 = Foo2->new; +ok(my $ref2 = $foo2->one, 'value returned'); +ok(Scalar::Util::isweak($foo2->{one}), 'value weakened'); +undef $ref2; +ok(!defined $foo->{one}, 'weak value gone'); # test readonly SVs sub mk_ref { \ 'yay' };