start pushing constructor inlining back into the metaclass
Jesse Luehrs [Thu, 11 Nov 2010 05:29:35 +0000 (23:29 -0600)]
lib/Class/MOP/Class.pm
lib/Class/MOP/Method/Constructor.pm
t/010_self_introspection.t

index b0ba266..983dd48 100644 (file)
@@ -584,6 +584,100 @@ sub _construct_instance {
     return $instance;
 }
 
+sub _inline_new_object {
+    my $self = shift;
+
+    my $idx = 0;
+    return (
+        'my $class = shift;',
+        'return Class::MOP::Class->initialize($class)->new_object(@_)',
+            'if $class ne \'' . $self->name . '\';',
+        'my $params = @_ == 1 ? $_[0] : {@_};',
+        'my $instance = ' . $self->_inline_create_instance('$class') . ';',
+        (map { $self->_inline_slot_initializer($_, $idx++) }
+             $self->get_all_attributes),
+        $self->_inline_preserve_weak_metaclasses,
+        'return $instance',
+    );
+}
+
+sub _inline_create_instance {
+    my $self = shift;
+
+    return $self->get_meta_instance->inline_create_instance(@_);
+}
+
+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 get_meta_instance {
     my $self = shift;
@@ -604,13 +698,7 @@ sub _create_meta_instance {
     return $instance;
 }
 
-sub inline_create_instance {
-    my $self = shift;
-
-    return $self->get_meta_instance->inline_create_instance(@_);
-}
-
-sub inline_rebless_instance {
+sub _inline_rebless_instance {
     my $self = shift;
 
     return $self->get_meta_instance->inline_rebless_instance_structure(@_);
@@ -1572,13 +1660,6 @@ metaclass.
 Returns an instance of the C<instance_metaclass> 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
index 3755a4e..b64c1c5 100644 (file)
@@ -89,10 +89,6 @@ sub _initialize_body {
     $self->{'body'} = $self->$method_name;
 }
 
-sub _generate_constructor_method {
-    return sub { Class::MOP::Class->initialize(shift)->new_object(@_) }
-}
-
 sub _eval_environment {
     my $self = shift;
     my $defaults = [map { $_->default } @{ $self->_attributes }];
@@ -101,23 +97,18 @@ sub _eval_environment {
     };
 }
 
+sub _generate_constructor_method {
+    return sub { Class::MOP::Class->initialize(shift)->new_object(@_) }
+}
+
 sub _generate_constructor_method_inline {
     my $self = shift;
 
     my $meta = $self->associated_metaclass;
 
-    my $idx = 0;
     my @source = (
         'sub {',
-            'my $class = shift;',
-            'return Class::MOP::Class->initialize($class)->new_object(@_)',
-                'if $class ne \'' . $meta->name . '\';',
-            'my $params = @_ == 1 ? $_[0] : {@_};',
-            'my $instance = ' . $meta->inline_create_instance('$class') . ';',
-            (map { $self->_generate_slot_initializer($_, $idx++) }
-                 @{ $self->_attributes }),
-            $self->_preserve_weak_metaclasses,
-            'return $instance',
+            $meta->_inline_new_object,
         '}',
     );
 
@@ -134,78 +125,6 @@ sub _generate_constructor_method_inline {
     return $code;
 }
 
-sub _generate_slot_initializer {
-    my $self  = shift;
-    my ($attr, $idx) = @_;
-
-    my $default = $self->_generate_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 _preserve_weak_metaclasses {
-    my $self = shift;
-    my $meta = $self->associated_metaclass;
-    if (Class::MOP::metaclass_is_weak($meta->name)) {
-        return (
-            $meta->_inline_set_mop_slot(
-                '$instance', 'Class::MOP::class_of($class)'
-            ) . ';'
-        );
-    }
-    else {
-        return ();
-    }
-}
-
-sub _generate_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;
-    }
-}
-
 1;
 
 __END__
index 99cbc87..90d2f69 100644 (file)
@@ -58,11 +58,13 @@ my @class_mop_class_methods = qw(
     create_anon_class is_anon_class
 
     instance_metaclass get_meta_instance
-    inline_create_instance
-    inline_rebless_instance
+    _inline_create_instance
+    _inline_rebless_instance
     _inline_get_mop_slot _inline_set_mop_slot _inline_clear_mop_slot
     create_meta_instance _create_meta_instance
     new_object clone_object
+    _inline_new_object _inline_default_value _inline_preserve_weak_metaclasses
+    _inline_slot_initializer
     construct_instance _construct_instance
     construct_class_instance _construct_class_instance
     clone_instance _clone_instance