X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FClass.pm;h=891e611d7f5f467ea9ae967c7ce8d54436a53da3;hb=cc66fac6ef15584503dfcbc1953da2d58aad7989;hp=2f71fa196e162864bb38fa7008e1dde09974ad71;hpb=301d65f26c8dffbce037d89208788bf21c40a7b1;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Class.pm b/lib/Class/MOP/Class.pm index 2f71fa1..891e611 100644 --- a/lib/Class/MOP/Class.pm +++ b/lib/Class/MOP/Class.pm @@ -17,7 +17,7 @@ use Devel::GlobalDestruction 'in_global_destruction'; use Try::Tiny; use List::MoreUtils 'all'; -our $VERSION = '1.10'; +our $VERSION = '1.11'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -181,18 +181,6 @@ sub _new { }, $class; } -sub reset_package_cache_flag { (shift)->{'_package_cache_flag'} = undef } -sub update_package_cache_flag { - my $self = shift; - # NOTE: - # we can manually update the cache number - # since we are actually adding the method - # to our cache as well. This avoids us - # having to regenerate the method_map. - # - SL - $self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name); -} - ## Metaclass compatibility { my %base_metaclass = ( @@ -549,18 +537,6 @@ sub create { return $meta; } -## Attribute readers - -# NOTE: -# all these attribute readers will be bootstrapped -# away in the Class::MOP bootstrap section - -sub instance_metaclass { $_[0]->{'instance_metaclass'} } -sub immutable_trait { $_[0]->{'immutable_trait'} } -sub constructor_class { $_[0]->{'constructor_class'} } -sub constructor_name { $_[0]->{'constructor_name'} } -sub destructor_class { $_[0]->{'destructor_class'} } - # Instance Construction & Cloning sub new_object { @@ -608,6 +584,141 @@ sub _construct_instance { return $instance; } +sub _inline_new_object { + my $self = shift; + + return ( + 'my $class = shift;', + '$class = Scalar::Util::blessed($class) || $class;', + $self->_inline_fallback_constructor('$class'), + $self->_inline_params('$params', '$class'), + $self->_inline_generate_instance('$instance', '$class'), + $self->_inline_slot_initializers, + $self->_inline_preserve_weak_metaclasses, + $self->_inline_extra_init, + 'return $instance', + ); +} + +sub _inline_fallback_constructor { + my $self = shift; + my ($class) = @_; + return ( + 'return ' . $self->_generate_fallback_constructor($class), + 'if ' . $class . ' ne \'' . $self->name . '\';', + ); +} + +sub _generate_fallback_constructor { + my $self = shift; + my ($class) = @_; + return 'Class::MOP::Class->initialize(' . $class . ')->new_object(@_)', +} + +sub _inline_params { + my $self = shift; + my ($params, $class) = @_; + return ( + 'my ' . $params . ' = @_ == 1 ? $_[0] : {@_};', + ); +} + +sub _inline_generate_instance { + my $self = shift; + my ($inst, $class) = @_; + return ( + 'my ' . $inst . ' = ' . $self->_inline_create_instance($class) . ';', + ); +} + +sub _inline_create_instance { + my $self = shift; + + return $self->get_meta_instance->inline_create_instance(@_); +} + +sub _inline_slot_initializers { + my $self = shift; + + my $idx = 0; + + return map { $self->_inline_slot_initializer($_, $idx++) } + sort { $a->name cmp $b->name } $self->get_all_attributes; +} + +sub _inline_slot_initializer { + my $self = shift; + my ($attr, $idx) = @_; + + my $default = $self->_inline_default_value($attr, $idx); + + if (defined(my $init_arg = $attr->init_arg)) { + my @source = ( + 'if (exists $params->{\'' . $init_arg . '\'}) {', + $attr->_inline_set_value( + '$instance', '$params->{\'' . $init_arg . '\'}' + ), + '}', + ); + if (defined $default) { + push @source, ( + 'else {', + $attr->_inline_set_value('$instance', $default), + '}', + ); + } + return @source; + } + elsif (defined $default) { + return $attr->_inline_set_value('$instance', $default); + } + else { + return (); + } +} + +sub _inline_default_value { + my $self = shift; + my ($attr, $index) = @_; + + if ($attr->has_default) { + # NOTE: + # default values can either be CODE refs + # in which case we need to call them. Or + # they can be scalars (strings/numbers) + # in which case we can just deal with them + # in the code we eval. + if ($attr->is_default_a_coderef) { + return '$defaults->[' . $index . ']->($instance)'; + } + else { + return '$defaults->[' . $index . ']'; + } + } + elsif ($attr->has_builder) { + return '$instance->' . $attr->builder; + } + else { + return; + } +} + +sub _inline_preserve_weak_metaclasses { + my $self = shift; + if (Class::MOP::metaclass_is_weak($self->name)) { + return ( + $self->_inline_set_mop_slot( + '$instance', 'Class::MOP::class_of($class)' + ) . ';' + ); + } + else { + return (); + } +} + +sub _inline_extra_init { } + sub get_meta_instance { my $self = shift; @@ -628,16 +739,28 @@ sub _create_meta_instance { return $instance; } -sub inline_create_instance { +sub _inline_rebless_instance { my $self = shift; - return $self->get_meta_instance->inline_create_instance(@_); + return $self->get_meta_instance->inline_rebless_instance_structure(@_); } -sub inline_rebless_instance { +sub _inline_get_mop_slot { my $self = shift; - return $self->get_meta_instance->inline_rebless_instance_structure(@_); + return $self->get_meta_instance->_inline_get_mop_slot(@_); +} + +sub _inline_set_mop_slot { + my $self = shift; + + return $self->get_meta_instance->_inline_set_mop_slot(@_); +} + +sub _inline_clear_mop_slot { + my $self = shift; + + return $self->get_meta_instance->_inline_clear_mop_slot(@_); } sub clone_object { @@ -815,8 +938,7 @@ sub get_all_attributes { sub superclasses { my $self = shift; - my $isa = $self->get_or_add_package_symbol( - { sigil => '@', type => 'ARRAY', name => 'ISA' } ); + my $isa = $self->get_or_add_package_symbol('@ISA'); if (@_) { my @supers = @_; @@ -1579,13 +1701,6 @@ metaclass. Returns an instance of the C to be used in the construction of a new instance of the class. -=item B<< $metaclass->inline_create_instance($class_var) >> - -=item B<< $metaclass->inline_rebless_instance($instance_var, $class_var) >> - -These methods takes variable names, and use them to create an inline snippet -of code that will create a new instance of the class. - =back =head2 Informational predicates