Merge branch 'stable'
[gitmo/Class-MOP.git] / lib / Class / MOP / Attribute.pm
index 751a6b9..bf61239 100644 (file)
@@ -10,7 +10,7 @@ use Carp         'confess';
 use Scalar::Util 'blessed', 'weaken';
 use Try::Tiny;
 
-our $VERSION   = '1.05';
+our $VERSION   = '1.12';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
@@ -148,18 +148,24 @@ sub _set_initial_slot_value {
     return $meta_instance->set_slot_value($instance, $slot_name, $value)
         unless $self->has_initializer;
 
-    my $callback = sub {
-        $meta_instance->set_slot_value($instance, $slot_name, $_[0]);
-    };
-    
+    my $callback = $self->_make_initializer_writer_callback(
+        $meta_instance, $instance, $slot_name
+    );
+
     my $initializer = $self->initializer;
 
     # most things will just want to set a value, so make it first arg
     $instance->$initializer($value, $callback, $self);
 }
 
-sub associated_class   { $_[0]->{'associated_class'}   }
-sub associated_methods { $_[0]->{'associated_methods'} }
+sub _make_initializer_writer_callback {
+    my $self = shift;
+    my ($meta_instance, $instance, $slot_name) = @_;
+
+    return sub {
+        $meta_instance->set_slot_value($instance, $slot_name, $_[0]);
+    };
+}
 
 sub get_read_method  { 
     my $self   = shift;    
@@ -258,38 +264,91 @@ sub set_initial_value {
 }
 
 sub set_value { shift->set_raw_value(@_) }
-sub get_value { shift->get_raw_value(@_) }
 
 sub set_raw_value {
-    my ($self, $instance, $value) = @_;
+    my $self = shift;
+    my ($instance, $value) = @_;
 
-    Class::MOP::Class->initialize(ref($instance))
-                     ->get_meta_instance
-                     ->set_slot_value($instance, $self->name, $value);
+    my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
+    return $mi->set_slot_value($instance, $self->name, $value);
 }
 
+sub _inline_set_value {
+    my $self = shift;
+    return $self->_inline_instance_set(@_) . ';';
+}
+
+sub _inline_instance_set {
+    my $self = shift;
+    my ($instance, $value) = @_;
+
+    my $mi = $self->associated_class->get_meta_instance;
+    return $mi->inline_set_slot_value($instance, $self->name, $value);
+}
+
+sub get_value { shift->get_raw_value(@_) }
+
 sub get_raw_value {
-    my ($self, $instance) = @_;
+    my $self = shift;
+    my ($instance) = @_;
+
+    my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
+    return $mi->get_slot_value($instance, $self->name);
+}
+
+sub _inline_get_value {
+    my $self = shift;
+    return $self->_inline_instance_get(@_) . ';';
+}
+
+sub _inline_instance_get {
+    my $self = shift;
+    my ($instance) = @_;
 
-    Class::MOP::Class->initialize(ref($instance))
-                     ->get_meta_instance
-                     ->get_slot_value($instance, $self->name);
+    my $mi = $self->associated_class->get_meta_instance;
+    return $mi->inline_get_slot_value($instance, $self->name);
 }
 
 sub has_value {
-    my ($self, $instance) = @_;
+    my $self = shift;
+    my ($instance) = @_;
 
-    Class::MOP::Class->initialize(ref($instance))
-                     ->get_meta_instance
-                     ->is_slot_initialized($instance, $self->name);
+    my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
+    return $mi->is_slot_initialized($instance, $self->name);
+}
+
+sub _inline_has_value {
+    my $self = shift;
+    return $self->_inline_instance_has(@_) . ';';
+}
+
+sub _inline_instance_has {
+    my $self = shift;
+    my ($instance) = @_;
+
+    my $mi = $self->associated_class->get_meta_instance;
+    return $mi->inline_is_slot_initialized($instance, $self->name);
 }
 
 sub clear_value {
-    my ($self, $instance) = @_;
+    my $self = shift;
+    my ($instance) = @_;
 
-    Class::MOP::Class->initialize(ref($instance))
-                     ->get_meta_instance
-                     ->deinitialize_slot($instance, $self->name);
+    my $mi = Class::MOP::Class->initialize(ref($instance))->get_meta_instance;
+    return $mi->deinitialize_slot($instance, $self->name);
+}
+
+sub _inline_clear_value {
+    my $self = shift;
+    return $self->_inline_instance_clear(@_) . ';';
+}
+
+sub _inline_instance_clear {
+    my $self = shift;
+    my ($instance) = @_;
+
+    my $mi = $self->associated_class->get_meta_instance;
+    return $mi->inline_deinitialize_slot($instance, $self->name);
 }
 
 ## load em up ...
@@ -894,6 +953,18 @@ attribute.
 This does not currently remove methods from the list returned by
 C<associated_methods>.
 
+=item B<< $attr->inline_get >>
+
+=item B<< $attr->inline_set >>
+
+=item B<< $attr->inline_has >>
+
+=item B<< $attr->inline_clear >>
+
+These methods return a code snippet suitable for inlining the relevant
+operation. They expect strings containing variable names to be used in the
+inlining, like C<'$self'> or C<'$_[1]'>.
+
 =back
 
 =head2 Introspection