use Sub::Name 'subname';
use Devel::GlobalDestruction 'in_global_destruction';
-our $VERSION = '0.86';
+our $VERSION = '0.88';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
my $class = shift;
my $params = @_ == 1 ? $_[0] : {@_};
my $meta_instance = $class->get_meta_instance();
- my $instance = $meta_instance->create_instance();
+ # FIXME:
+ # the code below is almost certainly incorrect
+ # but this is foreign inheritance, so we might
+ # have to kludge it in the end.
+ my $instance = $params->{__INSTANCE__} || $meta_instance->create_instance();
foreach my $attr ($class->get_all_attributes()) {
$attr->initialize_instance_slot($meta_instance, $instance, $params);
}
my ( $current_package, $current_name ) = Class::MOP::get_code_info($body);
- if ( $current_name eq '__ANON__' ) {
+ if ( !defined $current_name || $current_name eq '__ANON__' ) {
my $full_method_name = ($self->name . '::' . $method_name);
subname($full_method_name => $body);
}
$self->get_attribute_map->{$attribute->name} = $attribute;
# invalidate package flag here
- my $e = do { local $@; eval { $attribute->install_accessors() }; $@ };
+ my $e = do {
+ local $@;
+ local $SIG{__DIE__};
+ eval { $attribute->install_accessors() };
+ $@;
+ };
if ( $e ) {
$self->remove_attribute($attribute->name);
die $e;
sub is_mutable { 1 }
sub is_immutable { 0 }
-sub immutable_transformer { return }
sub _immutable_options {
my ( $self, @args ) = @_;
my $class_name;
if ( $meta_attr and $trait eq $meta_attr->default ) {
-
- # if the trait is the same as the default we try and pick a predictable
- # name for the immutable metaclass
- $class_name = "Class::MOP::Class::Immutable::" . ref($self);
+ # if the trait is the same as the default we try and pick a
+ # predictable name for the immutable metaclass
+ $class_name = 'Class::MOP::Class::Immutable::' . ref($self);
}
else {
- $class_name
- = join( "::", "Class::MOP::Class::Immutable::CustomTrait", $trait,
- "ForMetaClass", ref($self) );
+ $class_name = join '::', 'Class::MOP::Class::Immutable::CustomTrait',
+ $trait, 'ForMetaClass', ref($self);
}
if ( Class::MOP::is_class_loaded($class_name) ) {
else {
my @super = ( $trait, ref($self) );
- my $meta = Class::MOP::Class->initialize($class_name);
+ my $meta = $self->initialize($class_name);
$meta->superclasses(@super);
$meta->make_immutable;
This method is used to create a new object of the metaclass's
class. Any parameters you provide are used to initialize the
-instance's attributes.
+instance's attributes. A special C<__INSTANCE__> key can be passed to
+provide an already generated instance, rather than having Class::MOP
+generate it for you. This is mostly useful for using Class::MOP with
+foreign classes, which generally generate instances using their own
+constructor.
=item B<< $metaclass->instance_metaclass >>
This will return a L<Class::MOP::Attribute> for the specified
C<$attribute_name>. If the class does not have the specified
-attribute, it returns C<undef>.
+attribute, it returns C<undef>.
-NOTE that get_attribute does not search superclasses, for
-that you need to use C<find_attribute_by_name>.
+NOTE that get_attribute does not search superclasses, for that you
+need to use C<find_attribute_by_name>.
=item B<< $metaclass->has_attribute($attribute_name) >>
methods, and also allows us to optimize some methods on the metaclass
object itself.
+After immutabilization, the metaclass object will cache most
+informational methods such as C<get_method_map> and
+C<get_all_attributes>. Methods which would alter the class, such as
+C<add_attribute>, C<add_method>, and so on will throw an error on an
+immutable metaclass object.
+
The immutabilization system in L<Moose> takes much greater advantage
of the inlining features than Class::MOP itself does.
This method will create an immutable transformer and uses it to make
the class and its metaclass object immutable.
-Details of how immutabilization works are in L<Class::MOP::Immutable>
-documentation.
+This method accepts the following options:
-=item B<< $metaclass->make_mutable >>
+=over 8
-Calling this method reverse the immutabilization transformation.
+=item * inline_accessors
+
+=item * inline_constructor
+
+=item * inline_destructor
+
+These are all booleans indicating whether the specified method(s)
+should be inlined.
+
+By default, accessors and the constructor are inlined, but not the
+destructor.
+
+=item * immutable_trait
+
+The name of a class which will be used as a parent class for the
+metaclass object being made immutable. This "trait" implements the
+post-immutability functionality of the metaclass (but not the
+transformation itself).
+
+This defaults to L<Class::MOP::Class::Immutable::Trait>.
-=item B<< $metaclass->immutable_transformer >>
+=item * constructor_name
-If the class has been made immutable previously, this returns the
-L<Class::MOP::Immutable> object that was created to do the
-transformation.
+This is the constructor method name. This defaults to "new".
-If the class was never made immutable, this method will die.
+=item * constructor_class
+
+The name of the method metaclass for constructors. It will be used to
+generate the inlined constructor. This defaults to
+"Class::MOP::Method::Constructor".
+
+=item * replace_constructor
+
+This is a boolean indicating whether an existing constructor should be
+replaced when inlining a constructor. This defaults to false.
+
+=item * destructor_class
+
+The name of the method metaclass for destructors. It will be used to
+generate the inlined destructor. This defaults to
+"Class::MOP::Method::Denstructor".
+
+=item * replace_destructor
+
+This is a boolean indicating whether an existing destructor should be
+replaced when inlining a destructor. This defaults to false.
+
+=back
+
+=item B<< $metaclass->make_mutable >>
+
+Calling this method reverse the immutabilization transformation.
=back