fix weak lazy attributes (tome)
Jesse Luehrs [Thu, 17 Nov 2011 05:32:55 +0000 (23:32 -0600)]
Changes
lib/Moose/Meta/Attribute.pm
t/attributes/attribute_reader_generation.t

diff --git a/Changes b/Changes
index 0a34966..3234d75 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,11 @@ for, noteworthy changes.
 
 {{$NEXT}}
 
+  [BUG FIXES]
+
+  * Attributes with weak_ref now weaken their associated slot when they are
+    initialized through a lazy default or builder. Reported by tome. (doy)
+
 2.0400 Tue, Nov 15, 2011
 
   [OTHER]
index b314b59..9989d75 100644 (file)
@@ -749,7 +749,7 @@ sub _inline_weaken_value {
 
     my $mi = $self->associated_class->get_meta_instance;
     return (
-        $mi->inline_weaken_slot_value($instance, $self->name, $value),
+        $mi->inline_weaken_slot_value($instance, $self->name),
             'if ref ' . $value . ';',
     );
 }
@@ -825,6 +825,10 @@ sub get_value {
             $value = $self->_coerce_and_verify( $value, $instance );
 
             $self->set_initial_value($instance, $value);
+
+            if ( ref $value && $self->is_weak_ref ) {
+                $self->_weaken_value($instance);
+            }
         }
     }
 
@@ -906,6 +910,7 @@ sub _inline_init_from_default {
                $self->_inline_check_constraint($default, $tc, $message, $for_lazy))
             : (),
         $self->_inline_init_slot($instance, $default),
+        $self->_inline_weaken_value($instance, $default),
     );
 }
 
index 5c625e8..a3abdc0 100644 (file)
@@ -27,6 +27,16 @@ use Test::Fatal;
     };
     ::ok(!$@, '... created the lazy reader method okay') or warn $@;
 
+    eval {
+        has 'lazy_weak_foo' => (
+            reader => 'get_lazy_weak_foo',
+            lazy => 1,
+            default => sub { our $AREF = [] },
+            weak_ref => 1,
+        );
+    };
+    ::ok(!$@, '... created the lazy weak reader method okay') or warn $@;
+
     my $warn;
 
     eval {
@@ -55,6 +65,10 @@ use Test::Fatal;
     isnt( exception {
         $foo->get_lazy_foo(100);
     }, undef, '... get_lazy_foo is a read-only' );
+
+    is($foo->get_lazy_weak_foo(), $Foo::AREF, 'got the right value');
+    ok($foo->meta->get_meta_instance->slot_value_is_weak($foo, 'lazy_weak_foo'),
+       '... and it is weak');
 }
 
 {
@@ -72,6 +86,12 @@ use Test::Fatal;
     is( $attr->get_value($foo), 10, "lazy value" );
 
     is( $attr->get_raw_value($foo), 10, "raw value" );
+
+    my $lazy_weak_attr = $foo->meta->find_attribute_by_name("lazy_weak_foo");
+
+    is( $lazy_weak_attr->get_value($foo), $Foo::AREF, "it's the right value" );
+
+    ok( $foo->meta->get_meta_instance->slot_value_is_weak($foo, 'lazy_weak_foo'), "and it is weak");
 }
 
 {