From: Shawn M Moore Date: Sat, 25 Jul 2009 16:31:31 +0000 (-0400) Subject: Report all method conflicts, not just the first X-Git-Tag: 0.89~31 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e893345ecab3343db02dc7f3fea7fec06982fd2a;p=gitmo%2FMoose.git Report all method conflicts, not just the first --- diff --git a/Changes b/Changes index 887de48..a94a295 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,12 @@ next version * Moose::Manual::Attributes - Clarify "is", include discussion of "bare". (Sartak) + * Moose::Meta::Role::Method::Conflicting + * Moose::Meta::Role::Application::ToClass + - For the first set of roles involved in a conflict, report all + unresolved method conflicts, not just the first method. Fixes #47210 + reported by Ovid. (Sartak) + 0.88 Fri Jul 24, 2009 * Moose::Manual::Contributing - Re-write the Moose::Manual::Contributing document to reflect diff --git a/lib/Moose/Meta/Role/Application/ToClass.pm b/lib/Moose/Meta/Role/Application/ToClass.pm index a9a5048..ffe09df 100644 --- a/lib/Moose/Meta/Role/Application/ToClass.pm +++ b/lib/Moose/Meta/Role/Application/ToClass.pm @@ -77,16 +77,33 @@ sub check_required_methods { if (@conflicts) { my $conflict = $conflicts[0]; - my $roles = Moose::Util::english_list( map { q{'} . $_ . q{'} } @{ $conflict->roles } ); - - $error - .= "Due to a method name conflict in roles " - . $roles - . ", the method '" - . $conflict->name - . "' must be implemented or excluded by '" - . $class->name - . q{'}; + my $roles = $conflict->roles_as_english_list; + + my @same_role_conflicts = grep { $_->roles_as_english_list eq $roles } @conflicts; + + if (@same_role_conflicts == 1) { + $error + .= "Due to a method name conflict in roles " + . $roles + . ", the method '" + . $conflict->name + . "' must be implemented or excluded by '" + . $class->name + . q{'}; + } + else { + my $methods + = Moose::Util::english_list( map { q{'} . $_->name . q{'} } @same_role_conflicts ); + + $error + .= "Due to method name conflicts in roles " + . $roles + . ", the methods " + . $methods + . " must be implemented or excluded by '" + . $class->name + . q{'}; + } } elsif (@missing) { my $noun = @missing == 1 ? 'method' : 'methods'; diff --git a/lib/Moose/Meta/Role/Method/Conflicting.pm b/lib/Moose/Meta/Role/Method/Conflicting.pm index 2faca02..66130f2 100644 --- a/lib/Moose/Meta/Role/Method/Conflicting.pm +++ b/lib/Moose/Meta/Role/Method/Conflicting.pm @@ -4,6 +4,8 @@ package Moose::Meta::Role::Method::Conflicting; use strict; use warnings; +use Moose::Util; + use base qw(Moose::Meta::Role::Method::Required); our $VERSION = '0.88'; @@ -15,6 +17,11 @@ __PACKAGE__->meta->add_attribute('roles' => ( required => 1, )); +sub roles_as_english_list { + my $self = shift; + Moose::Util::english_list( map { q{'} . $_ . q{'} } @{ $self->roles } ); +} + 1; __END__ @@ -61,6 +68,10 @@ Returns the conflicting method's name, as provided to the constructor. Returns the roles that generated this conflicting method, as provided to the constructor. +=item B<< $method->roles_as_english_list >> + +Returns the roles that generated this conflicting method as an English list. + =back =head1 BUGS diff --git a/t/030_roles/043_conflict_many_methods.t b/t/030_roles/043_conflict_many_methods.t new file mode 100644 index 0000000..94f730f --- /dev/null +++ b/t/030_roles/043_conflict_many_methods.t @@ -0,0 +1,45 @@ +#!/usr/bin/perl +use strict; +use warnings; + +use Test::More tests => 2; +use Test::Exception; + +{ + package Bomb; + use Moose::Role; + + sub fuse { } + sub explode { } + + package Spouse; + use Moose::Role; + + sub fuse { } + sub explode { } + + package Caninish; + use Moose::Role; + + sub bark { } + + package Treeve; + use Moose::Role; + + sub bark { } +} + +package PracticalJoke; +use Moose; + +::throws_ok { + with 'Bomb', 'Spouse'; +} qr/Due to method name conflicts in roles 'Bomb' and 'Spouse', the methods 'explode' and 'fuse' must be implemented or excluded by 'PracticalJoke'/; + +::throws_ok { + with ( + 'Bomb', 'Spouse', + 'Caninish', 'Treeve', + ); +} qr/Due to method name conflicts in roles 'Bomb' and 'Spouse', the methods 'explode' and 'fuse' must be implemented or excluded by 'PracticalJoke'/; +