Fix clone_and_inherit_options() to take 'traits' and 'metaclass' correctly
gfx [Sun, 4 Oct 2009 06:07:25 +0000 (15:07 +0900)]
lib/Mouse/Meta/Attribute.pm
lib/Mouse/Meta/Class.pm
t/020_attributes/016_attribute_traits_registered.t

index 1946c96..0ee8400 100644 (file)
@@ -208,7 +208,7 @@ sub _create_args { # DEPRECATED
 }
 
 sub interpolate_class{
-    my($class, $name, $args) = @_;
+    my($class, $args) = @_;
 
     if(my $metaclass = delete $args->{metaclass}){
         $class = Mouse::Util::resolve_metaclass_alias( Attribute => $metaclass );
@@ -230,7 +230,6 @@ sub interpolate_class{
         }
 
         if (@traits) {
-            warn "traits [@traits] for $class\n";
             $class = Mouse::Meta::Class->create_anon_class(
                 superclasses => [ $class ],
                 roles        => \@traits,
@@ -321,10 +320,12 @@ sub _canonicalize_handles {
 }
 
 sub clone_and_inherit_options{
-    my $self = shift;
-    my $name = shift;
+    my($self, %args) = @_;
+
+    my($attribute_class, @traits) = ref($self)->interpolate_class(\%args);
 
-    return ref($self)->new($name, %{$self}, (@_ == 1) ? %{$_[0]} : @_);
+    $args{traits} = \@traits if @traits;
+    return $attribute_class->new($self->name, %{$self}, %args);
 }
 
 sub clone_parent { # DEPRECATED
index 45297bc..765def8 100644 (file)
@@ -104,6 +104,7 @@ sub add_attribute {
         if ($name =~ s/^\+//) { # inherited attributes
             my $inherited_attr;
 
+            # find_attribute_by_name
             foreach my $class($self->linearized_isa){
                 my $meta = Mouse::Util::get_metaclass_by_name($class) or next;
                 $inherited_attr = $meta->get_attribute($name) and last;
@@ -112,10 +113,10 @@ sub add_attribute {
             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);
+            $attr = $inherited_attr->clone_and_inherit_options(%args);
         }
         else{
-            my($attribute_class, @traits) = $self->attribute_metaclass->interpolate_class($name, \%args);
+            my($attribute_class, @traits) = $self->attribute_metaclass->interpolate_class(\%args);
             $args{traits} = \@traits if @traits;
 
             $attr = $attribute_class->new($name, %args);
index b9e57d4..1264c68 100755 (executable)
@@ -87,7 +87,10 @@ does_ok($bar_attr, 'My::Attribute::Trait');
 is($bar_attr->foo, "blah", "attr initialized");
 
 ok(!$bar_attr->meta->does_role('Aliased'), "does_role ignores aliases for sanity");
-ok($bar_attr->does('Aliased'), "attr->does uses aliases");
+{
+    local $TODO = 'Mouse does not support ->does($aliased)';
+    ok($bar_attr->does('Aliased'), "attr->does uses aliases");
+}
 ok(!$bar_attr->meta->does_role('Fictional'), "does_role returns false for nonexistent roles");
 ok(!$bar_attr->does('Fictional'), "attr->does returns false for nonexistent roles");
 
@@ -108,7 +111,10 @@ does_ok($derived_bar_attr, 'My::Other::Attribute::Trait' );
 is($derived_bar_attr->the_other_attr, "oink", "attr initialized" );
 
 ok(!$derived_bar_attr->meta->does_role('Aliased'), "does_role ignores aliases for sanity");
-ok($derived_bar_attr->does('Aliased'), "attr->does uses aliases");
+{
+    local $TODO = 'Mouse does not support ->does($aliased)';
+    ok($derived_bar_attr->does('Aliased'), "attr->does uses aliases");
+}
 ok(!$derived_bar_attr->meta->does_role('Fictional'), "does_role returns false for nonexistent roles");
 ok(!$derived_bar_attr->does('Fictional'), "attr->does returns false for nonexistent roles");