From: Jesse Luehrs Date: Fri, 1 Oct 2010 05:31:01 +0000 (-0500) Subject: also handle weakening in anon roles X-Git-Tag: 1.16~63 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6f73c55516ec2357f17bc19f8a8afbf08ee485ea;p=gitmo%2FMoose.git also handle weakening in anon roles --- diff --git a/lib/Moose/Meta/Role.pm b/lib/Moose/Meta/Role.pm index 3789245..3a459f4 100644 --- a/lib/Moose/Meta/Role.pm +++ b/lib/Moose/Meta/Role.pm @@ -161,12 +161,22 @@ $META->add_attribute( sub initialize { my $class = shift; my $pkg = shift; - return Class::MOP::get_metaclass_by_name($pkg) - || $class->SUPER::initialize( + + if (defined(my $meta = Class::MOP::get_metaclass_by_name($pkg))) { + return $meta; + } + + my %options = @_; + + my $meta = $class->SUPER::initialize( $pkg, 'attribute_metaclass' => 'Moose::Meta::Role::Attribute', - @_ - ); + %options, + ); + + Class::MOP::weaken_metaclass($pkg) if $options{weaken}; + + return $meta; } sub reinitialize { @@ -189,13 +199,19 @@ sub reinitialize { ); } + my %options = @_; + $options{weaken} = Class::MOP::metaclass_is_weak($meta->name) + if !exists $options{weaken} + && blessed($meta) + && $meta->isa('Moose::Meta::Role'); + # don't need to remove generated metaobjects here yet, since we don't # yet generate anything in roles. this may change in the future though... # keep an eye on that my $new_meta = $self->SUPER::reinitialize( $pkg, %existing_classes, - @_, + %options, ); $new_meta->_restore_metaobjects_from($meta) if $meta && $meta->isa('Moose::Meta::Role'); @@ -513,9 +529,6 @@ sub create { } } - Class::MOP::weaken_metaclass($meta->name) - if $meta->is_anon_role; - return $meta; } @@ -557,6 +570,7 @@ sub consumers { sub create_anon_role { my ($role, %options) = @_; + $options{weaken} = 1 unless exists $options{weaken}; my $package_name = $ANON_ROLE_PREFIX . ++$ANON_ROLE_SERIAL; return $role->create($package_name, %options); } diff --git a/t/030_roles/036_free_anonymous_roles.t b/t/030_roles/036_free_anonymous_roles.t index 855e2bf..6d06d23 100644 --- a/t/030_roles/036_free_anonymous_roles.t +++ b/t/030_roles/036_free_anonymous_roles.t @@ -33,4 +33,31 @@ ok(!$weak, "the role metaclass is freed after its last reference (from a consumi ok(!$name->can('improperly_freed'), "we blew away the role's symbol table entries"); +do { + my $anon_class; + + do { + my $role = Moose::Meta::Role->create_anon_role( + methods => { + improperly_freed => sub { 1 }, + }, + weaken => 0, + ); + weaken($weak = $role); + + $name = $role->name; + + $anon_class = Moose::Meta::Class->create_anon_class( + roles => [ $role->name ], + ); + }; + + ok($weak, "we still have the role metaclass because the anonymous class that consumed it is still alive"); + ok($name->can('improperly_freed'), "we have not blown away the role's symbol table"); +}; + +ok($weak, "the role metaclass still exists because we told it not to weaken"); + +ok($name->can('improperly_freed'), "the symbol table still exists too"); + done_testing;