use Try::Tiny;
use List::MoreUtils 'all';
-our $VERSION = '1.09';
+our $VERSION = '1.10';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
my $old_metaclass = blessed($options{package})
? $options{package}
: Class::MOP::get_metaclass_by_name($options{package});
+ $options{weaken} = Class::MOP::metaclass_is_weak($old_metaclass->name)
+ if !exists $options{weaken}
+ && blessed($old_metaclass)
+ && $old_metaclass->isa('Class::MOP::Class');
$old_metaclass->_remove_generated_metaobjects
if $old_metaclass && $old_metaclass->isa('Class::MOP::Class');
- my $new_metaclass = $class->SUPER::reinitialize(@args);
+ my $new_metaclass = $class->SUPER::reinitialize(%options);
$new_metaclass->_restore_metaobjects_from($old_metaclass)
if $old_metaclass && $old_metaclass->isa('Class::MOP::Class');
return $new_metaclass;
}
# NOTE:
# this will only work for a HASH instance type
- if ($class->is_anon_class) {
+ if (Class::MOP::metaclass_is_weak($class->name)) {
(reftype($instance) eq 'HASH')
|| confess "Currently only HASH based instances are supported with instance of anon-classes";
# NOTE:
$old_metaclass->rebless_instance_away($instance, $self, %params)
if $old_metaclass;
- if ($old_metaclass->is_anon_class) {
+ if (Class::MOP::metaclass_is_weak($old_metaclass->name)) {
delete $instance->{__MOP__};
}
# NOTE:
# this will only work for a HASH instance type
- if ($self->is_anon_class) {
+ if (Class::MOP::metaclass_is_weak($self->name)) {
(reftype($instance) eq 'HASH')
|| confess "Currently only HASH based instances are supported with instance of anon-classes";
# NOTE:
sub _superclasses_updated {
my $self = shift;
$self->update_meta_instance_dependencies();
+ # keep strong references to all our parents, so they don't disappear if
+ # they are anon classes and don't have any direct instances
+ $self->_superclass_metas(
+ map { Class::MOP::class_of($_) } $self->superclasses
+ );
+}
+
+sub _superclass_metas {
+ my $self = shift;
+ $self->{_superclass_metas} = [@_];
}
sub subclasses {
If it is not passed, C<meta> is assumed, and if C<undef> is explicitly
given, no meta method will be installed.
+=item * weaken
+
+If true, the metaclass that is stored in the global cache will be a
+weak reference.
+
+Classes created in this way are destroyed once the metaclass they are
+attached to goes out of scope, and will be removed from Perl's internal
+symbol table.
+
+All instances of a class with a weakened metaclass keep a special
+reference to the metaclass object, which prevents the metaclass from
+going out of scope while any instances exist.
+
+This only works if the instance is based on a hash reference, however.
+
=back
=item B<< Class::MOP::Class->create_anon_class(%options) >>
It accepts the same C<superclasses>, C<methods>, and C<attributes>
parameters that C<create> accepts.
-Anonymous classes are destroyed once the metaclass they are attached
-to goes out of scope, and will be removed from Perl's internal symbol
-table.
-
-All instances of an anonymous class keep a special reference to the
-metaclass object, which prevents the metaclass from going out of scope
-while any instances exist.
-
-This only works if the instance is based on a hash reference, however.
+Anonymous classes default to C<< weaken => 1 >>, although this can be
+overridden.
=item B<< Class::MOP::Class->initialize($package_name, %options) >>