Split role application to a module like Moose
[gitmo/Mouse.git] / lib / Mouse / Meta / Role / Composite.pm
index 7c29969..d7e004a 100644 (file)
@@ -1,9 +1,10 @@
 package Mouse::Meta::Role::Composite;
 use Mouse::Util; # enables strict and warnings
 use Mouse::Meta::Role;
+use Mouse::Meta::Role::Application;
 our @ISA = qw(Mouse::Meta::Role);
 
-sub get_method_list{
+sub get_method_list {
     my($self) = @_;
     return keys %{ $self->{methods} };
 }
@@ -38,20 +39,20 @@ sub get_method_body {
 
 sub has_method {
     # my($self, $method_name) = @_;
-    return 0; # to fool _apply_methods() in combine()
+    return 0; # to fool apply_methods() in combine()
 }
 
-sub has_attribute{
+sub has_attribute {
     # my($self, $method_name) = @_;
-    return 0; # to fool _appply_attributes() in combine()
+    return 0; # to fool appply_attributes() in combine()
 }
 
-sub has_override_method_modifier{
+sub has_override_method_modifier {
     # my($self, $method_name) = @_;
-    return 0; # to fool _apply_modifiers() in combine()
+    return 0; # to fool apply_modifiers() in combine()
 }
 
-sub add_attribute{
+sub add_attribute {
     my $self      = shift;
     my $attr_name = shift;
     my $spec      = (@_ == 1 ? $_[0] : {@_});
@@ -65,7 +66,7 @@ sub add_attribute{
     return;
 }
 
-sub add_override_method_modifier{
+sub add_override_method_modifier {
     my($self, $method_name, $code) = @_;
 
     my $existing = $self->{override_method_modifiers}{$method_name};
@@ -78,19 +79,30 @@ sub add_override_method_modifier{
     return;
 }
 
-# components of apply()
+sub apply {
+    my $self     = shift;
+    my $consumer = shift;
 
-sub _apply_methods{
-    my($self, $consumer, $args) = @_;
+    Mouse::Meta::Role::Application::RoleSummation->new(@_)->apply($self, $consumer);
+    return;
+}
+
+package Mouse::Meta::Role::Application::RoleSummation;
+our @ISA = qw(Mouse::Meta::Role::Application);
 
-    if(exists $self->{conflicting_methods}){
+sub apply_methods {
+    my($self, $role, $consumer, @extra) = @_;
+
+    if(exists $role->{conflicting_methods}){
         my $consumer_class_name = $consumer->name;
 
-        my @conflicting = grep{ !$consumer_class_name->can($_) } keys %{ $self->{conflicting_methods} };
+        my @conflicting = grep{ !$consumer_class_name->can($_) } 
+            keys %{ $role->{conflicting_methods} };
 
         if(@conflicting == 1){
             my $method_name = $conflicting[0];
-            my $roles       = Mouse::Util::quoted_english_list(map{ $_->name } @{ $self->{composed_roles_by_method}{$method_name} });
+            my $roles       = Mouse::Util::quoted_english_list( map{ $_->name }
+                @{ $role->{composed_roles_by_method}{$method_name} });
             $self->throw_error(
                sprintf q{Due to a method name conflict in roles %s, the method '%s' must be implemented or excluded by '%s'},
                    $roles, $method_name, $consumer_class_name
@@ -101,7 +113,7 @@ sub _apply_methods{
             my $roles = Mouse::Util::quoted_english_list(
                 grep{ !$seen{$_}++ } # uniq
                 map { $_->name }
-                map { @{$_} } @{ $self->{composed_roles_by_method} }{@conflicting}
+                map { @{$_} } @{ $role->{composed_roles_by_method} }{@conflicting}
             );
 
             $self->throw_error(
@@ -113,9 +125,11 @@ sub _apply_methods{
         }
     }
 
-    $self->SUPER::_apply_methods($consumer, $args);
+    $self->SUPER::apply_methods($role, $consumer, @extra);
     return;
 }
+
+package Mouse::Meta::Role::Composite;
 1;
 __END__