handle weakening of anon classes here too
Jesse Luehrs [Fri, 1 Oct 2010 04:47:06 +0000 (23:47 -0500)]
lib/Moose/Meta/Class.pm
t/010_basics/014_create_anon.t

index 09c433a..8bdc90d 100644 (file)
@@ -105,10 +105,15 @@ sub create_anon_class {
         return $ANON_CLASSES{$cache_key};
     }
 
+    $options{weaken} = !$cache_ok
+        unless exists $options{weaken};
+
     my $new_class = $self->SUPER::create_anon_class(%options);
 
-    $ANON_CLASSES{$cache_key} = $new_class
-        if $cache_ok;
+    if ($cache_ok) {
+        $ANON_CLASSES{$cache_key} = $new_class;
+        weaken($ANON_CLASSES{$cache_key});
+    }
 
     return $new_class;
 }
@@ -164,6 +169,7 @@ sub reinitialize {
 
     delete $ANON_CLASSES{$cache_key};
     $ANON_CLASSES{$new_cache_key} = $new_meta;
+    weaken($ANON_CLASSES{$new_cache_key});
 
     return $new_meta;
 }
@@ -408,8 +414,9 @@ sub _replace_self {
     # We need to replace the cached metaclass instance or else when it goes
     # out of scope Class::MOP::Class destroy's the namespace for the
     # metaclass's class, causing much havoc.
+    my $weaken = Class::MOP::metaclass_is_weak( $self->name );
     Class::MOP::store_metaclass_by_name( $self->name, $self );
-    Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
+    Class::MOP::weaken_metaclass( $self->name ) if $weaken;
 }
 
 sub _process_attribute {
index 978c40a..eda9afb 100644 (file)
@@ -84,4 +84,45 @@ use Moose::Meta::Class;
     can_ok( $name, 'meta' );
 }
 
+{
+    my $name;
+    {
+        my $meta = Moose::Meta::Class->create_anon_class(
+            superclasses => ['Class'],
+            cache        => 1,
+        );
+        $name = $meta->name;
+        ok(!Class::MOP::metaclass_is_weak($name), "cache implies weaken => 0");
+    }
+    ok(Class::MOP::class_of($name), "cache implies weaken => 0");
+    Class::MOP::remove_metaclass_by_name($name);
+}
+
+{
+    my $name;
+    {
+        my $meta = Moose::Meta::Class->create_anon_class(
+            superclasses => ['Class'],
+            cache        => 1,
+            weaken       => 1,
+        );
+        my $name = $meta->name;
+        ok(Class::MOP::metaclass_is_weak($name), "but we can override this");
+    }
+    ok(!Class::MOP::class_of($name), "but we can override this");
+    Class::MOP::remove_metaclass_by_name($name);
+}
+
+{
+    my $meta = Moose::Meta::Class->create_anon_class(
+        superclasses => ['Class'],
+        cache        => 1,
+    );
+    ok(!Class::MOP::metaclass_is_weak($meta->name),
+       "creates a nonweak metaclass");
+    Scalar::Util::weaken($meta);
+    Class::MOP::remove_metaclass_by_name($meta->name);
+    ok(!$meta, "removing a cached anon class means it's actually gone");
+}
+
 done_testing;