From: gfx Date: Fri, 25 Sep 2009 00:33:23 +0000 (+0900) Subject: Refactor attribute constructor X-Git-Tag: 0.35~32 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=commitdiff_plain;h=87ca293be7ca0041bbb86ad9609a498fb2010f4f;hp=ef9070cc6ee59ca3691f3765ad96ef0922e064ca Refactor attribute constructor --- diff --git a/lib/Mouse.pm b/lib/Mouse.pm index a18bef8..6c09a77 100644 --- a/lib/Mouse.pm +++ b/lib/Mouse.pm @@ -4,7 +4,7 @@ use warnings; use 5.006; use base 'Exporter'; -our $VERSION = '0.33'; +our $VERSION = '0.33_01'; use Carp 'confess'; use Scalar::Util 'blessed'; diff --git a/lib/Mouse/Meta/Attribute.pm b/lib/Mouse/Meta/Attribute.pm index 8511bc2..eccc881 100644 --- a/lib/Mouse/Meta/Attribute.pm +++ b/lib/Mouse/Meta/Attribute.pm @@ -10,26 +10,8 @@ use Mouse::Util; use Mouse::Meta::TypeConstraint; use Mouse::Meta::Method::Accessor; -sub BUILDARGS{ - my $class = shift; - my $name = shift; - my %args = (@_ == 1) ? %{$_[0]} : @_; - - $args{name} = $name; - - # XXX: for backward compatibility (with method modifiers) - if($class->can('canonicalize_args') != \&canonicalize_args){ - %args = $class->canonicalize_args($name, %args); - } - - return \%args; -} - -sub new { - my $class = shift; - my $args = $class->BUILDARGS(@_); - - my $name = $args->{name}; +sub _process_options{ + my($class, $name, $args) = @_; # taken from Class::MOP::Attribute::new @@ -137,11 +119,28 @@ sub new { || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it"); } - my $instance = bless $args, $class; + # XXX: for backward compatibility (with method modifiers) + if($class->can('canonicalize_args') != \&canonicalize_args){ + %{$args} = $class->canonicalize_args($name, %{$args}); + } + return; +} + +sub new { + my $class = shift; + my $name = shift; + + my %args = (@_ == 1) ? %{ $_[0] } : @_; + + $class->_process_options($name, \%args); + + $args{name} = $name; + + my $instance = bless \%args, $class; # extra attributes if($class ne __PACKAGE__){ - $class->meta->_initialize_instance($instance, $args); + $class->meta->_initialize_instance($instance,\%args); } # XXX: there is no fast way to check attribute validity @@ -217,16 +216,16 @@ sub _create_args { sub accessor_metaclass { 'Mouse::Meta::Method::Accessor' } -sub interpolate_class_and_new{ +sub interpolate_class{ my($class, $name, $args) = @_; if(my $metaclass = delete $args->{metaclass}){ $class = Mouse::Util::resolve_metaclass_alias( Attribute => $metaclass ); } - + my @traits; if(my $traits_ref = delete $args->{traits}){ - my @traits; + for (my $i = 0; $i < @{$traits_ref}; $i++) { my $trait = Mouse::Util::resolve_metaclass_alias(Attribute => $traits_ref->[$i], trait => 1); @@ -245,19 +244,17 @@ sub interpolate_class_and_new{ roles => \@traits, cache => 1, )->name; - - $args->{traits} = \@traits; } } - return $class->new($name, $args); + return( $class, @traits ); } sub canonicalize_args{ my ($self, $name, %args) = @_; Carp::cluck("$self->canonicalize_args has been deprecated." - . "Use \$self->BUILDARGS instead."); + . "Use \$self->_process_options instead."); return %args; } diff --git a/lib/Mouse/Meta/Class.pm b/lib/Mouse/Meta/Class.pm index 06c4f35..cea2064 100644 --- a/lib/Mouse/Meta/Class.pm +++ b/lib/Mouse/Meta/Class.pm @@ -78,40 +78,48 @@ sub get_all_method_names { $self->linearized_isa; } -sub _process_attribute{ +sub add_attribute { my $self = shift; - my $name = shift; - - my $args = (@_ == 1) ? $_[0] : { @_ }; - defined($name) - or $self->throw_error('You must provide a name for the attribute'); + my($attr, $name); - if ($name =~ s/^\+//) { - my $inherited_attr; - - foreach my $class($self->linearized_isa){ - my $meta = Mouse::Meta::Module::get_metaclass_by_name($class) or next; - $inherited_attr = $meta->get_attribute($name) and last; - } + if(blessed $_[0]){ + $attr = $_[0]; - defined($inherited_attr) - or $self->throw_error("Could not find an attribute by the name of '$name' to inherit from in ".$self->name); + $attr->isa('Mouse::Meta::Attribute') + || $self->throw_error("Your attribute must be an instance of Mouse::Meta::Attribute (or a subclass)"); - return $inherited_attr->clone_and_inherit_options($name, $args); + $name = $attr->name; } else{ - return Mouse::Meta::Attribute->interpolate_class_and_new($name, $args); - } -} + # _process_attribute + $name = shift; -sub add_attribute { - my $self = shift; + my %args = (@_ == 1) ? %{$_[0]} : @_; - my $attr = blessed($_[0]) ? $_[0] : $self->_process_attribute(@_); + defined($name) + or $self->throw_error('You must provide a name for the attribute'); - $attr->isa('Mouse::Meta::Attribute') - || $self->throw_error("Your attribute must be an instance of Mouse::Meta::Attribute (or a subclass)"); + if ($name =~ s/^\+//) { # inherited attributes + my $inherited_attr; + + foreach my $class($self->linearized_isa){ + my $meta = Mouse::Meta::Module::get_metaclass_by_name($class) or next; + $inherited_attr = $meta->get_attribute($name) and last; + } + + defined($inherited_attr) + or $self->throw_error("Could not find an attribute by the name of '$name' to inherit from in ".$self->name); + + $attr = $inherited_attr->clone_and_inherit_options($name, \%args); + } + else{ + my($attribute_class, @traits) = Mouse::Meta::Attribute->interpolate_class($name, \%args); + $args{traits} = \@traits if @traits; + + $attr = $attribute_class->new($name, \%args); + } + } weaken( $attr->{associated_class} = $self );