Fix the delegation rule
Fuji, Goro [Mon, 27 Sep 2010 12:44:36 +0000 (21:44 +0900)]
Moose-t-failing/020_attributes/011_more_attr_delegation.t [deleted file]
lib/Mouse/Meta/Attribute.pm
t/020_attributes/011_more_attr_delegation.t

diff --git a/Moose-t-failing/020_attributes/011_more_attr_delegation.t b/Moose-t-failing/020_attributes/011_more_attr_delegation.t
deleted file mode 100644 (file)
index c588848..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/perl
-# This is automatically generated by author/import-moose-test.pl.
-# DO NOT EDIT THIS FILE. ANY CHANGES WILL BE LOST!!!
-use t::lib::MooseCompat;
-
-use strict;
-use warnings;
-
-use Test::More;
-$TODO = q{Mouse is not yet completed};
-use Test::Exception;
-
-=pod
-
-This tests the more complex
-delegation cases and that they
-do not fail at compile time.
-
-=cut
-
-{
-
-    package ChildASuper;
-    use Mouse;
-
-    sub child_a_super_method { "as" }
-
-    package ChildA;
-    use Mouse;
-
-    extends "ChildASuper";
-
-    sub child_a_method_1 { "a1" }
-    sub child_a_method_2 { Scalar::Util::blessed($_[0]) . " a2" }
-
-    package ChildASub;
-    use Mouse;
-
-    extends "ChildA";
-
-    sub child_a_method_3 { "a3" }
-
-    package ChildB;
-    use Mouse;
-
-    sub child_b_method_1 { "b1" }
-    sub child_b_method_2 { "b2" }
-    sub child_b_method_3 { "b3" }
-
-    package ChildC;
-    use Mouse;
-
-    sub child_c_method_1 { "c1" }
-    sub child_c_method_2 { "c2" }
-    sub child_c_method_3_la { "c3" }
-    sub child_c_method_4_la { "c4" }
-
-    package ChildD;
-    use Mouse;
-
-    sub child_d_method_1 { "d1" }
-    sub child_d_method_2 { "d2" }
-
-    package ChildE;
-    # no Mouse
-
-    sub new { bless {}, shift }
-    sub child_e_method_1 { "e1" }
-    sub child_e_method_2 { "e2" }
-
-    package ChildF;
-    # no Mouse
-
-    sub new { bless {}, shift }
-    sub child_f_method_1 { "f1" }
-    sub child_f_method_2 { "f2" }
-
-    package ChildG;
-    use Mouse;
-
-    sub child_g_method_1 { "g1" }
-
-    package ChildH;
-    use Mouse;
-
-    sub child_h_method_1 { "h1" }
-    sub parent_method_1 { "child_parent_1" }
-
-    package ChildI;
-    use Mouse;
-
-    sub child_i_method_1 { "i1" }
-    sub parent_method_1 { "child_parent_1" }
-
-    package Parent;
-    use Mouse;
-
-    sub parent_method_1 { "parent_1" }
-    ::can_ok('Parent', 'parent_method_1');
-
-    ::dies_ok {
-        has child_a => (
-            is      => "ro",
-            default => sub { ChildA->new },
-            handles => qr/.*/,
-        );
-    } "all_methods requires explicit isa";
-
-    ::lives_ok {
-        has child_a => (
-            isa     => "ChildA",
-            is      => "ro",
-            default => sub { ChildA->new },
-            handles => qr/.*/,
-        );
-    } "allow all_methods with explicit isa";
-
-    ::lives_ok {
-        has child_b => (
-            is      => 'ro',
-            default => sub { ChildB->new },
-            handles => [qw/child_b_method_1/],
-        );
-    } "don't need to declare isa if method list is predefined";
-
-    ::lives_ok {
-        has child_c => (
-            isa     => "ChildC",
-            is      => "ro",
-            default => sub { ChildC->new },
-            handles => qr/_la$/,
-        );
-    } "can declare regex collector";
-
-    ::dies_ok {
-        has child_d => (
-            is      => "ro",
-            default => sub { ChildD->new },
-            handles => sub {
-                my ( $class, $delegate_class ) = @_;
-            }
-        );
-    } "can't create attr with generative handles parameter and no isa";
-
-    ::lives_ok {
-        has child_d => (
-            isa     => "ChildD",
-            is      => "ro",
-            default => sub { ChildD->new },
-            handles => sub {
-                my ( $class, $delegate_class ) = @_;
-                return;
-            }
-        );
-    } "can't create attr with generative handles parameter and no isa";
-
-    ::lives_ok {
-        has child_e => (
-            isa     => "ChildE",
-            is      => "ro",
-            default => sub { ChildE->new },
-            handles => ["child_e_method_2"],
-        );
-    } "can delegate to non moose class using explicit method list";
-
-    my $delegate_class;
-    ::lives_ok {
-        has child_f => (
-            isa     => "ChildF",
-            is      => "ro",
-            default => sub { ChildF->new },
-            handles => sub {
-                $delegate_class = $_[1]->name;
-                return;
-            },
-        );
-    } "subrefs on non moose class give no meta";
-
-    ::is( $delegate_class, "ChildF", "plain classes are handed down to subs" );
-
-    ::lives_ok {
-        has child_g => (
-            isa     => "ChildG",
-            default => sub { ChildG->new },
-            handles => ["child_g_method_1"],
-        );
-    } "can delegate to object even without explicit reader";
-
-    ::can_ok('Parent', 'parent_method_1');
-    ::dies_ok {
-        has child_h => (
-            isa     => "ChildH",
-            is      => "ro",
-            default => sub { ChildH->new },
-            handles => sub { map { $_, $_ } $_[1]->get_all_method_names },
-        );
-    } "Can't override exisiting class method in delegate";
-    ::can_ok('Parent', 'parent_method_1');
-
-    ::lives_ok {
-        has child_i => (
-            isa     => "ChildI",
-            is      => "ro",
-            default => sub { ChildI->new },
-            handles => sub {
-                map { $_, $_ } grep { !/^parent_method_1|meta$/ }
-                    $_[1]->get_all_method_names;
-            },
-        );
-    } "Test handles code ref for skipping predefined methods";
-
-
-    sub parent_method { "p" }
-}
-
-# sanity
-
-isa_ok( my $p = Parent->new, "Parent" );
-isa_ok( $p->child_a, "ChildA" );
-isa_ok( $p->child_b, "ChildB" );
-isa_ok( $p->child_c, "ChildC" );
-isa_ok( $p->child_d, "ChildD" );
-isa_ok( $p->child_e, "ChildE" );
-isa_ok( $p->child_f, "ChildF" );
-isa_ok( $p->child_i, "ChildI" );
-
-ok(!$p->can('child_g'), '... no child_g accessor defined');
-ok(!$p->can('child_h'), '... no child_h accessor defined');
-
-
-is( $p->parent_method, "p", "parent method" );
-is( $p->child_a->child_a_super_method, "as", "child supermethod" );
-is( $p->child_a->child_a_method_1, "a1", "child method" );
-
-can_ok( $p, "child_a_super_method" );
-can_ok( $p, "child_a_method_1" );
-can_ok( $p, "child_a_method_2" );
-ok( !$p->can( "child_a_method_3" ), "but not subclass of delegate class" );
-
-is( $p->child_a_method_1, $p->child_a->child_a_method_1, "delegate behaves the same" );
-is( $p->child_a_method_2, "ChildA a2", "delegates are their own invocants" );
-
-
-can_ok( $p, "child_b_method_1" );
-ok( !$p->can("child_b_method_2"), "but not ChildB's unspecified siblings" );
-
-
-ok( !$p->can($_), "none of ChildD's methods ($_)" )
-    for grep { /^child/ } map { $_->name } ChildD->meta->get_all_methods();
-
-can_ok( $p, "child_c_method_3_la" );
-can_ok( $p, "child_c_method_4_la" );
-
-is( $p->child_c_method_3_la, "c3", "ChildC method delegated OK" );
-
-can_ok( $p, "child_e_method_2" );
-ok( !$p->can("child_e_method_1"), "but not child_e_method_1");
-
-is( $p->child_e_method_2, "e2", "delegate to non moose class (child_e_method_2)" );
-
-can_ok( $p, "child_g_method_1" );
-is( $p->child_g_method_1, "g1", "delegate to moose class without reader (child_g_method_1)" );
-
-can_ok( $p, "child_i_method_1" );
-is( $p->parent_method_1, "parent_1", "delegate doesn't override existing method" );
-
-done_testing;
index 736c814..bb5c05f 100644 (file)
@@ -263,8 +263,9 @@ sub install_accessors{
     # install delegation
     if(exists $attribute->{handles}){
         my %handles = $attribute->_canonicalize_handles();
-
         while(my($handle, $method_to_call) = each %handles){
+            next if Mouse::Object->can($handle);
+
             if($metaclass->has_method($handle)) {
                 $attribute->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation");
             }
@@ -298,7 +299,7 @@ sub _canonicalize_handles {
     elsif ($handle_type eq 'Regexp') {
         my $meta = $self->_find_delegate_metaclass();
         return map  { $_ => $_ }
-               grep { !Mouse::Object->can($_) && $_ =~ $handles }
+               grep { /$handles/ }
                    Mouse::Util::is_a_metarole($meta)
                         ? $meta->get_method_list
                         : $meta->get_all_method_names;
index 75d6fa1..5d958c2 100644 (file)
@@ -1,9 +1,12 @@
 #!/usr/bin/perl
+# This is automatically generated by author/import-moose-test.pl.
+# DO NOT EDIT THIS FILE. ANY CHANGES WILL BE LOST!!!
+use t::lib::MooseCompat;
 
 use strict;
 use warnings;
 
-use Test::More tests => 39;
+use Test::More;
 use Test::Exception;
 
 =pod
@@ -76,9 +79,24 @@ do not fail at compile time.
 
     sub child_g_method_1 { "g1" }
 
+    package ChildH;
+    use Mouse;
+
+    sub child_h_method_1 { "h1" }
+    sub parent_method_1 { "child_parent_1" }
+
+    package ChildI;
+    use Mouse;
+
+    sub child_i_method_1 { "i1" }
+    sub parent_method_1 { "child_parent_1" }
+
     package Parent;
     use Mouse;
 
+    sub parent_method_1 { "parent_1" }
+    ::can_ok('Parent', 'parent_method_1');
+
     ::dies_ok {
         has child_a => (
             is      => "ro",
@@ -167,11 +185,34 @@ do not fail at compile time.
         );
     } "can delegate to object even without explicit reader";
 
+    ::can_ok('Parent', 'parent_method_1');
+    ::dies_ok {
+        has child_h => (
+            isa     => "ChildH",
+            is      => "ro",
+            default => sub { ChildH->new },
+            handles => sub { map { $_, $_ } $_[1]->get_all_method_names },
+        );
+    } "Can't override exisiting class method in delegate";
+    ::can_ok('Parent', 'parent_method_1');
+
+    ::lives_ok {
+        has child_i => (
+            isa     => "ChildI",
+            is      => "ro",
+            default => sub { ChildI->new },
+            handles => sub {
+                map { $_, $_ } grep { !/^parent_method_1|meta$/ }
+                    $_[1]->get_all_method_names;
+            },
+        );
+    } "Test handles code ref for skipping predefined methods";
+
+
     sub parent_method { "p" }
 }
 
 # sanity
-
 isa_ok( my $p = Parent->new, "Parent" );
 isa_ok( $p->child_a, "ChildA" );
 isa_ok( $p->child_b, "ChildB" );
@@ -179,9 +220,12 @@ isa_ok( $p->child_c, "ChildC" );
 isa_ok( $p->child_d, "ChildD" );
 isa_ok( $p->child_e, "ChildE" );
 isa_ok( $p->child_f, "ChildF" );
+isa_ok( $p->child_i, "ChildI" );
 
 ok(!$p->can('child_g'), '... no child_g accessor defined');
-
+{ local $TODO = 'Mouse does not install delegations atomically';
+ok(!$p->can('child_h'), '... no child_h accessor defined');
+}
 
 is( $p->parent_method, "p", "parent method" );
 is( $p->child_a->child_a_super_method, "as", "child supermethod" );
@@ -215,3 +259,8 @@ is( $p->child_e_method_2, "e2", "delegate to non moose class (child_e_method_2)"
 
 can_ok( $p, "child_g_method_1" );
 is( $p->child_g_method_1, "g1", "delegate to moose class without reader (child_g_method_1)" );
+
+can_ok( $p, "child_i_method_1" );
+is( $p->parent_method_1, "parent_1", "delegate doesn't override existing method" );
+
+done_testing;