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