X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FAttribute.pm;h=609d6739772099aac887affe9f382460ee6f1b9d;hb=16e960bd460d404b809a1e5c24ba77405643342b;hp=c4c0d6bf4efd9ceec73c871d92510531a8601850;hpb=495af5181ab3a346f2271c3b1a981e355941e2c4;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Attribute.pm b/lib/Class/MOP/Attribute.pm index c4c0d6b..609d673 100644 --- a/lib/Class/MOP/Attribute.pm +++ b/lib/Class/MOP/Attribute.pm @@ -7,7 +7,7 @@ use warnings; use Carp 'confess'; use Scalar::Util 'blessed', 'reftype', 'weaken'; -our $VERSION = '0.08'; +our $VERSION = '0.09'; sub meta { require Class::MOP::Class; @@ -15,7 +15,7 @@ sub meta { } # NOTE: (meta-circularity) -# This method will be replaces in the +# This method will be replaced in the # boostrap section of Class::MOP, by # a new version which uses the # &Class::MOP::Class::construct_instance @@ -49,7 +49,7 @@ sub new { # NOTE: # this is a primative (and kludgy) clone operation -# for now, it will be repleace in the Class::MOP +# for now, it will be replaced in the Class::MOP # bootstrap with a proper one, however we know # that this one will work fine for now. sub clone { @@ -132,15 +132,31 @@ sub detach_from_class { $self->{associated_class} = undef; } +## Slot management + +sub set_value { + my ( $self, $instance, $value ) = @_; + + Class::MOP::Class->initialize(Scalar::Util::blessed($instance)) + ->get_meta_instance + ->set_slot_value( $instance, $self->name, $value ); +} + +sub get_value { + my ( $self, $instance ) = @_; + + Class::MOP::Class->initialize(Scalar::Util::blessed($instance)) + ->get_meta_instance + ->get_slot_value( $instance, $self->name ); +} + ## Method generation helpers sub generate_accessor_method { - my $self = shift; - my $attr_name = $self->name; + my $attr = shift; return sub { - my $meta_instance = Class::MOP::Class->initialize(Scalar::Util::blessed($_[0]))->get_meta_instance; - $meta_instance->set_slot_value($_[0], $attr_name, $_[1]) if scalar(@_) == 2; - $meta_instance->get_slot_value($_[0], $attr_name); + $attr->set_value( $_[0], $_[1] ) if scalar(@_) == 2; + $attr->get_value( $_[0] ); }; } @@ -150,8 +166,8 @@ sub generate_accessor_method_inline { my $meta_instance = $self->associated_class->instance_metaclass; my $code = eval 'sub {' - . $meta_instance->inline_set_slot_value('$_[0]', $attr_name, '$_[1]') . ' if scalar(@_) == 2; ' - . $meta_instance->inline_get_slot_value('$_[0]', $attr_name) + . $meta_instance->inline_set_slot_value('$_[0]', "'$attr_name'", '$_[1]') . ' if scalar(@_) == 2; ' + . $meta_instance->inline_get_slot_value('$_[0]', "'$attr_name'") . '}'; confess "Could not generate inline accessor because : $@" if $@; @@ -159,13 +175,10 @@ sub generate_accessor_method_inline { } sub generate_reader_method { - my $self = shift; - my $attr_name = $self->name; + my $attr = shift; return sub { confess "Cannot assign a value to a read-only accessor" if @_ > 1; - Class::MOP::Class->initialize(Scalar::Util::blessed($_[0])) - ->get_meta_instance - ->get_slot_value($_[0], $attr_name); + $attr->get_value( $_[0] ); }; } @@ -176,7 +189,7 @@ sub generate_reader_method_inline { my $code = eval 'sub {' . 'confess "Cannot assign a value to a read-only accessor" if @_ > 1;' - . $meta_instance->inline_get_slot_value('$_[0]', $attr_name) + . $meta_instance->inline_get_slot_value('$_[0]', "'$attr_name'") . '}'; confess "Could not generate inline accessor because : $@" if $@; @@ -184,12 +197,9 @@ sub generate_reader_method_inline { } sub generate_writer_method { - my $self = shift; - my $attr_name = $self->name; - return sub { - Class::MOP::Class->initialize(Scalar::Util::blessed($_[0])) - ->get_meta_instance - ->set_slot_value($_[0], $attr_name, $_[1]); + my $attr = shift; + return sub { + $attr->set_value( $_[0], $_[1] ); }; } @@ -199,7 +209,7 @@ sub generate_writer_method_inline { my $meta_instance = $self->associated_class->instance_metaclass; my $code = eval 'sub {' - . $meta_instance->inline_set_slot_value('$_[0]', $attr_name, '$_[1]') + . $meta_instance->inline_set_slot_value('$_[0]', "'$attr_name'", '$_[1]') . '}'; confess "Could not generate inline accessor because : $@" if $@; @@ -222,7 +232,7 @@ sub generate_predicate_method_inline { my $meta_instance = $self->associated_class->instance_metaclass; my $code = eval 'sub {' - . 'defined ' . $meta_instance->inline_get_slot_value('$_[0]', $attr_name) . ' ? 1 : 0' + . 'defined ' . $meta_instance->inline_get_slot_value('$_[0]', "'$attr_name'") . ' ? 1 : 0' . '}'; confess "Could not generate inline accessor because : $@" if $@; @@ -234,7 +244,7 @@ sub process_accessors { if (reftype($accessor)) { (reftype($accessor) eq 'HASH') || confess "bad accessor/reader/writer/predicate format, must be a HASH ref"; - my ($name, $method) = each %{$accessor}; + my ($name, $method) = %{$accessor}; return ($name, Class::MOP::Attribute::Accessor->wrap($method)); } else { @@ -473,6 +483,22 @@ defined, and false (C<0>) otherwise. =back +=head2 Value management + +=over 4 + +=item set_value $instance, $value + +Set the value without going through the accessor. Note that this may be done to +even attributes with just read only accessors. + +=item get_value $instance + +Return the value without going through the accessor. Note that this may be done +even to attributes with just write only accessors. + +=back + =head2 Informational These are all basic read-only value accessors for the values @@ -627,4 +653,5 @@ L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. -=cut \ No newline at end of file +=cut +