MethodConflict exception
[gitmo/Moose.git] / lib / Moose / Exception / MethodConflict.pm
1 package Moose::Exception::MethodConflict;
2 use Moose;
3 extends 'Moose::Exception';
4
5 has '+message' => (
6     required => 0,
7     builder  => '_build_message',
8 );
9
10 has consumer => (
11     is       => 'ro',
12     isa      => 'Moose::Meta::Class',
13     required => 1,
14 );
15
16 has roles => (
17     traits   => ['Array'],
18     isa      => 'ArrayRef[RoleName]', # XXX we should have objects here
19     lazy     => 1,
20     default  => sub { shift->_first_method->roles },
21     handles  => {
22         roles => 'elements',
23     },
24 );
25
26 has methods => (
27     traits   => ['Array'],
28     isa      => 'ArrayRef[Moose::Meta::Role::Method::Conflicting]',
29     required => 1,
30     handles  => {
31         methods       => 'elements',
32         _first_method => [ get => 0 ],
33     },
34 );
35
36 sub _build_message {
37     my $self = shift;
38
39     my $class = $self->consumer;
40     my @conflicts = $self->methods;
41     my $conflict = $self->_first_method;
42     my $roles = $conflict->roles_as_english_list;
43
44     my @same_role_conflicts = grep { $_->roles_as_english_list eq $roles } @conflicts;
45
46     if (@same_role_conflicts == 1) {
47         return "Due to a method name conflict in roles "
48                .  $roles
49                . ", the method '"
50                . $conflict->name
51                . "' must be implemented or excluded by '"
52                . $class->name
53                . q{'};
54     }
55     else {
56         my $methods
57             = Moose::Util::english_list( map { q{'} . $_->name . q{'} } @same_role_conflicts );
58
59         return "Due to method name conflicts in roles "
60              .  $roles
61              . ", the methods "
62              . $methods
63              . " must be implemented or excluded by '"
64              . $class->name
65              . q{'};
66     }
67 }
68
69 1;
70