need to use a consistent sort order, now that this isn't cached
[gitmo/Class-MOP.git] / lib / Class / MOP / Class.pm
index b2fafd9..891e611 100644 (file)
@@ -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,13 +739,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(@_);
@@ -833,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 = @_;
@@ -1597,13 +1701,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