Moose::throw_error -> Moose->throw_error
[gitmo/Moose.git] / lib / Moose / Meta / Role / Application / ToRole.pm
CommitLineData
fb1e11d5 1package Moose::Meta::Role::Application::ToRole;
2
3use strict;
4use warnings;
5use metaclass;
6
fb1e11d5 7use Scalar::Util 'blessed';
8
e606ae5f 9our $VERSION = '0.57';
10$VERSION = eval $VERSION;
fb1e11d5 11our $AUTHORITY = 'cpan:STEVAN';
12
13use base 'Moose::Meta::Role::Application';
14
1c9db35c 15sub apply {
c4538447 16 my ($self, $role1, $role2) = @_;
17 $self->SUPER::apply($role1, $role2);
18 $role2->add_role($role1);
1c9db35c 19}
20
21sub check_role_exclusions {
22 my ($self, $role1, $role2) = @_;
c245d69b 23 Moose->throw_error("Conflict detected: " . $role2->name . " excludes role '" . $role1->name . "'")
1c9db35c 24 if $role2->excludes_role($role1->name);
25 foreach my $excluded_role_name ($role1->get_excluded_roles_list) {
c245d69b 26 Moose->throw_error("The class " . $role2->name . " does the excluded role '$excluded_role_name'")
1c9db35c 27 if $role2->does_role($excluded_role_name);
28 $role2->add_excluded_roles($excluded_role_name);
29 }
30}
31
32sub check_required_methods {
33 my ($self, $role1, $role2) = @_;
34 foreach my $required_method_name ($role1->get_required_method_list) {
3e19778d 35
36 next if $self->is_aliased_method($required_method_name);
37
1c9db35c 38 $role2->add_required_methods($required_method_name)
39 unless $role2->find_method_by_name($required_method_name);
40 }
41}
42
709c321c 43sub check_required_attributes {
44
45}
46
1c9db35c 47sub apply_attributes {
48 my ($self, $role1, $role2) = @_;
49 foreach my $attribute_name ($role1->get_attribute_list) {
50 # it if it has one already
51 if ($role2->has_attribute($attribute_name) &&
52 # make sure we haven't seen this one already too
53 $role2->get_attribute($attribute_name) != $role1->get_attribute($attribute_name)) {
c245d69b 54 Moose->throw_error("Role '" . $role1->name . "' has encountered an attribute conflict " .
4c0b3599 55 "during composition. This is fatal error and cannot be disambiguated.");
1c9db35c 56 }
57 else {
58 $role2->add_attribute(
59 $attribute_name,
60 $role1->get_attribute($attribute_name)
61 );
62 }
63 }
64}
65
66sub apply_methods {
67 my ($self, $role1, $role2) = @_;
68 foreach my $method_name ($role1->get_method_list) {
c4538447 69
43a41ede 70 next if $self->is_method_excluded($method_name);
db9476b1 71
72 if ($self->is_method_aliased($method_name)) {
73 my $aliased_method_name = $self->get_method_aliases->{$method_name};
74 # it if it has one already
75 if ($role2->has_method($aliased_method_name) &&
76 # and if they are not the same thing ...
77 $role2->get_method($aliased_method_name)->body != $role1->get_method($method_name)->body) {
c245d69b 78 Moose->throw_error("Cannot create a method alias if a local method of the same name exists");
db9476b1 79 }
80
81 $role2->alias_method(
82 $aliased_method_name,
83 $role1->get_method($method_name)
84 );
85
86 if (!$role2->has_method($method_name)) {
87 $role2->add_required_methods($method_name);
88 }
89
90 next;
91 }
3e19778d 92
1c9db35c 93 # it if it has one already
94 if ($role2->has_method($method_name) &&
95 # and if they are not the same thing ...
96 $role2->get_method($method_name)->body != $role1->get_method($method_name)->body) {
97 # method conflicts between roles result
98 # in the method becoming a requirement
99 $role2->add_required_methods($method_name);
100 }
101 else {
102 # add it, although it could be overriden
103 $role2->alias_method(
104 $method_name,
43a41ede 105 $role1->get_method($method_name)
1c9db35c 106 );
43a41ede 107
1c9db35c 108 }
43a41ede 109
1c9db35c 110 }
111}
112
113sub apply_override_method_modifiers {
114 my ($self, $role1, $role2) = @_;
115 foreach my $method_name ($role1->get_method_modifier_list('override')) {
116 # it if it has one already then ...
117 if ($role2->has_method($method_name)) {
118 # if it is being composed into another role
119 # we have a conflict here, because you cannot
120 # combine an overriden method with a locally
121 # defined one
c245d69b 122 Moose->throw_error("Role '" . $role1->name . "' has encountered an 'override' method conflict " .
1c9db35c 123 "during composition (A local method of the same name as been found). This " .
4c0b3599 124 "is fatal error.");
1c9db35c 125 }
126 else {
127 # if we are a role, we need to make sure
128 # we dont have a conflict with the role
129 # we are composing into
130 if ($role2->has_override_method_modifier($method_name) &&
131 $role2->get_override_method_modifier($method_name) != $role2->get_override_method_modifier($method_name)) {
c245d69b 132 Moose->throw_error("Role '" . $role1->name . "' has encountered an 'override' method conflict " .
1c9db35c 133 "during composition (Two 'override' methods of the same name encountered). " .
4c0b3599 134 "This is fatal error.");
1c9db35c 135 }
136 else {
137 # if there is no conflict,
138 # just add it to the role
139 $role2->add_override_method_modifier(
140 $method_name,
141 $role1->get_override_method_modifier($method_name)
142 );
143 }
144 }
145 }
146}
147
148sub apply_method_modifiers {
149 my ($self, $modifier_type, $role1, $role2) = @_;
150 my $add = "add_${modifier_type}_method_modifier";
151 my $get = "get_${modifier_type}_method_modifiers";
152 foreach my $method_name ($role1->get_method_modifier_list($modifier_type)) {
153 $role2->$add(
154 $method_name,
155 $_
156 ) foreach $role1->$get($method_name);
157 }
158}
159
1c9db35c 160
fb1e11d5 1611;
162
163__END__
164
165=pod
166
167=head1 NAME
168
ab76842e 169Moose::Meta::Role::Application::ToRole - Compose a role into another role
fb1e11d5 170
171=head1 DESCRIPTION
172
173=head2 METHODS
174
175=over 4
176
177=item B<new>
178
179=item B<meta>
180
1c9db35c 181=item B<apply>
182
709c321c 183=item B<check_role_exclusions>
184
1c9db35c 185=item B<check_required_methods>
186
709c321c 187=item B<check_required_attributes>
1c9db35c 188
189=item B<apply_attributes>
190
191=item B<apply_methods>
192
193=item B<apply_method_modifiers>
194
1c9db35c 195=item B<apply_override_method_modifiers>
196
fb1e11d5 197=back
198
199=head1 BUGS
200
201All complex software has bugs lurking in it, and this module is no
202exception. If you find a bug please either email me, or add the bug
203to cpan-RT.
204
205=head1 AUTHOR
206
207Stevan Little E<lt>stevan@iinteractive.comE<gt>
208
209=head1 COPYRIGHT AND LICENSE
210
778db3ac 211Copyright 2006-2008 by Infinity Interactive, Inc.
fb1e11d5 212
213L<http://www.iinteractive.com>
214
215This library is free software; you can redistribute it and/or modify
216it under the same terms as Perl itself.
217
218=cut
219