Clarify difference between trigger & after method modifier
[gitmo/Moose.git] / lib / Moose / Manual / Roles.pod
CommitLineData
ef45e915 1=pod
2
3=head1 NAME
4
5Moose::Manual::Roles - Roles, an Alternative to Deep Hierarchies and Base Classes
6
7=head1 WHAT IS A ROLE?
8
9A role is something that classes do. Usually, a role encapsulates some
10piece of behavior or state that can be shared between classes. It is
11important to understand that I<roles are not classes>. Roles do not
ca426a3a 12participate in inheritance, and a role cannot be instantiated. We
13sometimes say that classes I<consume> roles.
ef45e915 14
15Instead, a role is I<composed> into a class. In practical terms, this
16means that all of the methods and attributes defined in a role are
ca426a3a 17added directly to (we sometimes say "flattened into") the class that
18consumes the role. These attributes and methods then appear as if they
19were defined in the class itself.
ef45e915 20
21Moose roles are similar to mixins or interfaces in other languages.
22
23Besides defining their own methods and attributes, roles can also
24require that the consuming class define certain methods of its
25own. You could have a role that consisted only of a list of required
26methods, in which case the role would be very much like a Java
27interface.
28
29=head1 A SIMPLE ROLE
30
31Creating a role looks a lot like creating a Moose class:
32
33 package Breakable;
34
35 use Moose::Role;
36
37 has 'is_broken' => (
38 is => 'rw',
39 isa => 'Bool',
40 );
41
42 sub break {
43 my $self = shift;
44
45 print "I broke\n";
46
47 $self->is_broken(1);
48 }
49
0c39debe 50Except for our use of L<Moose::Role>, this looks just like a class
ef45e915 51definition with Moose. However, this is not a class, and it cannot be
52instantiated.
53
54Instead, its attributes and methods will be composed into classes
55which use the role:
56
57 package Car;
58
59 use Moose;
60
61 with 'Breakable';
62
63 has 'engine' => (
64 is => 'ro',
65 isa => 'Engine',
66 );
67
68The C<with> function composes roles into a class. Once that is done,
69the C<Car> class has an C<is_broken> attribute and a C<break>
70method. The C<Car> class also C<does('Breakable')>:
71
c56e5db4 72 my $car = Car->new( engine => Engine->new );
ef45e915 73
c56e5db4 74 print $car->is_broken ? 'Still working' : 'Busted';
75 $car->break;
76 print $car->is_broken ? 'Still working' : 'Busted';
ef45e915 77
78 $car->does('Breakable'); # true
79
80This prints:
81
82 Still working
83 I broke
84 Busted
85
86We could use this same role in a C<Bone> class:
87
88 package Bone;
89
90 use Moose;
91
92 with 'Breakable';
93
94 has 'marrow' => (
95 is => 'ro',
96 isa => 'Marrow',
97 );
98
99=head1 REQUIRED METHODS
100
101As mentioned previously, a role can require that consuming classes
102provide one or more methods. Using our C<Breakable> example, let's
103make it require that consuming classes implement their own C<break>
104methods:
105
106 package Breakable;
107
108 use Moose::Role;
109
110 requires 'break';
111
112 has 'is_broken' => (
113 is => 'rw',
114 isa => 'Bool',
115 );
116
117 after 'break' => sub {
118 my $self = shift;
119
120 $self->is_broken(1);
c56e5db4 121 };
ef45e915 122
123If we try to consume this role in a class that does not have a
124C<break> method, we will get an exception.
125
ca426a3a 126You can see that we added a method modifier on C<break>. We want
127classes that consume this role to implement their own logic for
128breaking, but we make sure that the C<is_broken> attribute is always
129set to true when C<break> is called.
ef45e915 130
131 package Car
132
ca426a3a 133 use Moose;
ef45e915 134
135 with 'Breakable';
136
137 has 'engine' => (
138 is => 'ro',
139 isa => 'Engine',
140 );
141
142 sub break {
143 my $self = shift;
144
c56e5db4 145 if ( $self->is_moving ) {
146 $self->stop;
ef45e915 147 }
148 }
149
150=head1 USING METHOD MODIFIERS
151
152Method modifiers and roles are a very powerful combination. Often, a
153role will combine method modifiers and required methods. We already
154saw one example with our C<Breakable> example.
155
eb169874 156Method modifiers increase the complexity of roles, because they make
c56e5db4 157the role application order relevant. If a class uses multiple roles,
158each of which modify the same method, those modifiers will be applied
159in the same order as the roles are used:
eb169874 160
161 package MovieCar;
162
163 use Moose;
164
165 extends 'Car';
166
167 with 'Breakable', 'ExplodesOnBreakage';
168
169Assuming that the new C<ExplodesOnBreakage> method I<also> has an
170C<after> modifier on C<break>, the C<after> modifiers will run one
171after the other. The modifier from C<Breakable> will run first, then
172the one from C<ExplodesOnBreakage>.
173
174=head1 METHOD CONFLICTS
175
176If a class composes multiple roles, and those roles have methods of
177the same name, we will have a conflict. In that case, the composing
178class is required to provide its I<own> method of the same name.
179
180 package Breakdances;
181
182 use Moose::Role
183
184 sub break {
185
186 }
187
188If we compose both C<Breakable> and C<Breakdancer> in a class, we must
189provide our own C<break> method:
190
191 package FragileDancer;
192
193 use Moose;
194
195 with 'Breakable', 'Breakdancer';
ef45e915 196
c56e5db4 197 sub break { ... }
198
199=head1 METHOD EXCLUSION AND ALIASING
200
201If we want our C<FragileDancer> class to be able to call the methods
202from both its roles, we can alias the methods:
203
204 package FragileDancer;
205
206 use Moose;
207
208 with 'Breakable' => { alias => { break => 'break_bone' } },
209 'Breakdancer' => { alias => { break => 'break_dance' } };
210
211However, aliasing a method simply makes a I<copy> of the method with
212the new name. We also need to exclude the original name:
213
214 with 'Breakable' => {
215 alias => { break => 'break_bone' },
216 exclude => 'break',
217 },
218 'Breakdancer' => {
219 alias => { break => 'break_dance' },
220 exclude => 'break',
221 };
222
223The exclude parameter prevents the C<break> method from being composed
224into the C<FragileDancer> class, so we don't have a conflict. This
225means that C<FragileDancer> does not need to implement its own
226C<break> method.
227
228This is useful, but it's worth noting that this breaks the contract
229implicit in consuming a role. Our C<FragileDancer> class does both the
230C<Breakable> and C<BreakDancer>, but does not provide a C<break>
231method. If some API expects an object that does one of those roles, it
232probably expects it to implement that method.
233
ca426a3a 234In some use cases we might alias and exclude methods from roles, but
235then provide a method of the same name in the class itself.
236
237=head1 ROLE EXCLUSION
238
239A role can say that it cannot be combined with some other role. This
240should be used with great caution, since it limits the re-usability of
241the role.
242
243 package Breakable;
244
245 use Moose::Role;
246
247 excludes 'BreakDancer';
248
a4bd85ad 249=head1 AUTHOR
250
251Dave Rolsky E<lt>autarch@urth.orgE<gt>
252
253=head1 COPYRIGHT AND LICENSE
254
2840a3b2 255Copyright 2009 by Infinity Interactive, Inc.
a4bd85ad 256
257L<http://www.iinteractive.com>
258
259This library is free software; you can redistribute it and/or modify
260it under the same terms as Perl itself.
261
262=cut