From: Jesse Luehrs Date: Fri, 2 Apr 2010 19:09:09 +0000 (-0500) Subject: reinitialize the metaclasses, rather than just reblessing X-Git-Tag: 1.05~23 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cf7febc71681a9410ba5e9807b9e9e97f0694725;p=gitmo%2FMoose.git reinitialize the metaclasses, rather than just reblessing --- diff --git a/lib/Moose/Meta/Class.pm b/lib/Moose/Meta/Class.pm index 1eec1a6..e383d5e 100644 --- a/lib/Moose/Meta/Class.pm +++ b/lib/Moose/Meta/Class.pm @@ -531,7 +531,16 @@ sub _fix_class_metaclass_incompatibility { # XXX: this doesn't work! we're reblessing $self into a subclass of # $super_meta, not of itself... probably do need to just go ahead and # reinitialize things here - $class_meta_subclass_meta->rebless_instance($self); + my $new_self = $class_meta_subclass_meta->name->reinitialize( + $self->name, + ); + %$self = %$new_self; + bless $self, $class_meta_subclass_meta->name; + # 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. + Class::MOP::store_metaclass_by_name( $self->name, $self ); + Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class; } } @@ -544,7 +553,17 @@ sub _fix_single_metaclass_incompatibility { if ($self->_can_fix_single_metaclass_incompatibility_by_role_reconciliation($metaclass_type, $super_meta)) { my %metaclasses = $self->_base_metaclasses; my $class_specific_meta_subclass_meta = $self->_reconcile_roles_for_metaclass($self->$metaclass_type, $super_meta->$metaclass_type); - $self->$metaclass_type($class_specific_meta_subclass_meta->name); + my $new_self = $super_meta->reinitialize( + $self->name, + $metaclass_type => $class_specific_meta_subclass_meta->name, + ); + %$self = %$new_self; + bless $self, blessed($super_meta); + # 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. + Class::MOP::store_metaclass_by_name( $self->name, $self ); + Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class; } }