1Moose::Manual::Roles(3)User Contributed Perl DocumentatioMnoose::Manual::Roles(3)
2
3
4
6 Moose::Manual::Roles - Roles, an alternative to deep hierarchies and
7 base classes
8
10 A role is something that classes do. Usually, a role encapsulates some
11 piece of behavior or state that can be shared between classes. It is
12 important to understand that roles are not classes. You cannot inherit
13 from a role, and a role cannot be instantiated. We sometimes say that
14 roles are consumed, either by classes or other roles.
15
16 Instead, a role is composed into a class. In practical terms, this
17 means that all of the methods and attributes defined in a role are
18 added directly to (we sometimes say "flattened into") the class that
19 consumes the role. These attributes and methods then appear as if they
20 were defined in the class itself. A subclass of the consuming class
21 will inherit all of these methods and attributes.
22
23 Moose roles are similar to mixins or interfaces in other languages.
24
25 Besides defining their own methods and attributes, roles can also
26 require that the consuming class define certain methods of its own. You
27 could have a role that consisted only of a list of required methods, in
28 which case the role would be very much like a Java interface.
29
30 Note that attribute accessors also count as methods for the purposes of
31 satisfying the requirements of a role.
32
34 Creating a role looks a lot like creating a Moose class:
35
36 package Breakable;
37
38 use Moose::Role;
39
40 has 'is_broken' => (
41 is => 'rw',
42 isa => 'Bool',
43 );
44
45 sub break {
46 my $self = shift;
47
48 print "I broke\n";
49
50 $self->is_broken(1);
51 }
52
53 Except for our use of Moose::Role, this looks just like a class
54 definition with Moose. However, this is not a class, and it cannot be
55 instantiated.
56
57 Instead, its attributes and methods will be composed into classes which
58 use the role:
59
60 package Car;
61
62 use Moose;
63
64 with 'Breakable';
65
66 has 'engine' => (
67 is => 'ro',
68 isa => 'Engine',
69 );
70
71 The "with" function composes roles into a class. Once that is done, the
72 "Car" class has an "is_broken" attribute and a "break" method. The
73 "Car" class also "does('Breakable')":
74
75 my $car = Car->new( engine => Engine->new );
76
77 print $car->is_broken ? 'Busted' : 'Still working';
78 $car->break;
79 print $car->is_broken ? 'Busted' : 'Still working';
80
81 $car->does('Breakable'); # true
82
83 This prints:
84
85 Still working
86 I broke
87 Busted
88
89 We could use this same role in a "Bone" class:
90
91 package Bone;
92
93 use Moose;
94
95 with 'Breakable';
96
97 has 'marrow' => (
98 is => 'ro',
99 isa => 'Marrow',
100 );
101
102 See also Moose::Cookbook::Roles::Recipe1 for an example.
103
105 As mentioned previously, a role can require that consuming classes
106 provide one or more methods. Using our "Breakable" example, let's make
107 it require that consuming classes implement their own "break" methods:
108
109 package Breakable;
110
111 use Moose::Role;
112
113 requires 'break';
114
115 has 'is_broken' => (
116 is => 'rw',
117 isa => 'Bool',
118 );
119
120 after 'break' => sub {
121 my $self = shift;
122
123 $self->is_broken(1);
124 };
125
126 If we try to consume this role in a class that does not have a "break"
127 method, we will get an exception.
128
129 You can see that we added a method modifier on "break". We want classes
130 that consume this role to implement their own logic for breaking, but
131 we make sure that the "is_broken" attribute is always set to true when
132 "break" is called.
133
134 package Car
135
136 use Moose;
137
138 with 'Breakable';
139
140 has 'engine' => (
141 is => 'ro',
142 isa => 'Engine',
143 );
144
145 sub break {
146 my $self = shift;
147
148 if ( $self->is_moving ) {
149 $self->stop;
150 }
151 }
152
153 Roles Versus Abstract Base Classes
154 If you are familiar with the concept of abstract base classes in other
155 languages, you may be tempted to use roles in the same way.
156
157 You can define an "interface-only" role, one that contains just a list
158 of required methods.
159
160 However, any class which consumes this role must implement all of the
161 required methods, either directly or through inheritance from a parent.
162 You cannot delay the method requirement check so that they can be
163 implemented by future subclasses.
164
165 Because the role defines the required methods directly, adding a base
166 class to the mix would not achieve anything. We recommend that you
167 simply consume the interface role in each class which implements that
168 interface.
169
170 Required Attributes
171 As mentioned before, a role requirement may also be satisfied by an
172 attribute accessor. But any "has" functions, which will generate
173 accessors that satisfy the role requirement, must be placed before the
174 "with" function that composes the role.
175
176 package Breakable;
177
178 use Moose::Role;
179
180 requires 'stress';
181
182 package Car;
183
184 use Moose;
185
186 has 'stress' => (
187 is => 'rw',
188 isa => 'Int',
189 );
190
191 with 'Breakable';
192
194 Method modifiers and roles are a very powerful combination. Often, a
195 role will combine method modifiers and required methods. We already saw
196 one example with our "Breakable" example.
197
198 Method modifiers increase the complexity of roles, because they make
199 the role application order relevant. If a class uses multiple roles,
200 each of which modify the same method, those modifiers will be applied
201 in the same order as the roles are used:
202
203 package MovieCar;
204
205 use Moose;
206
207 extends 'Car';
208
209 with 'Breakable', 'ExplodesOnBreakage';
210
211 Assuming that the new "ExplodesOnBreakage" method also has an "after"
212 modifier on "break", the "after" modifiers will run one after the
213 other. The modifier from "Breakable" will run first, then the one from
214 "ExplodesOnBreakage".
215
217 If a class composes multiple roles, and those roles have methods of the
218 same name, we will have a conflict. In that case, the composing class
219 is required to provide its own method of the same name.
220
221 package Breakdancer;
222
223 use Moose::Role
224
225 sub break {
226
227 }
228
229 If we compose both "Breakable" and "Breakdancer" in a class, we must
230 provide our own "break" method:
231
232 package FragileDancer;
233
234 use Moose;
235
236 with 'Breakable', 'Breakdancer';
237
238 sub break { ... }
239
240 A role can be a collection of other roles:
241
242 package Break::Bundle;
243
244 use Moose::Role;
245
246 with ('Breakable', 'Breakdancer');
247
249 If we want our "FragileDancer" class to be able to call the methods
250 from both its roles, we can alias the methods:
251
252 package FragileDancer;
253
254 use Moose;
255
256 with 'Breakable' => { -alias => { break => 'break_bone' } },
257 'Breakdancer' => { -alias => { break => 'break_dance' } };
258
259 However, aliasing a method simply makes a copy of the method with the
260 new name. We also need to exclude the original name:
261
262 with 'Breakable' => {
263 -alias => { break => 'break_bone' },
264 -excludes => 'break',
265 },
266 'Breakdancer' => {
267 -alias => { break => 'break_dance' },
268 -excludes => 'break',
269 };
270
271 The excludes parameter prevents the "break" method from being composed
272 into the "FragileDancer" class, so we don't have a conflict. This means
273 that "FragileDancer" does not need to implement its own "break" method.
274
275 This is useful, but it's worth noting that this breaks the contract
276 implicit in consuming a role. Our "FragileDancer" class does both the
277 "Breakable" and "BreakDancer", but does not provide a "break" method.
278 If some API expects an object that does one of those roles, it probably
279 expects it to implement that method.
280
281 In some use cases we might alias and exclude methods from roles, but
282 then provide a method of the same name in the class itself.
283
284 Also see Moose::Cookbook::Roles::Recipe2 for an example.
285
287 A role can say that it cannot be combined with some other role. This
288 should be used with great caution, since it limits the re-usability of
289 the role.
290
291 package Breakable;
292
293 use Moose::Role;
294
295 excludes 'BreakDancer';
296
298 A role can be applied to a class or an instance in other ways besides
299 using the 'with' syntax.
300
301 To apply a role to a class, use Moose::Util and the 'apply_all_roles'
302 function. If you apply the role to a class, it will affect all objects
303 of that class. You can't apply a role to a class if it has been made
304 immutable. In some circumstances it may make sense to make the class
305 mutable, apply the role, then make the class immutable again.
306
307 use Moose::Util;
308 ...
309 my $class = 'MyApp::Test';
310 $class->meta->make_mutable;
311 Moose::Util::apply_all_roles($class->meta, ('MyApp::SomeRole'));
312 $class->meta->make_immutable;
313
314 Do not apply roles to classes that have immutable subclasses, since
315 that will invalidate the metadata of the subclasses.
316
317 If you want the role to be applied only to a particular instance and
318 not to the class, you can apply the roles to the instance instead of
319 the class's meta:
320
321 Moose::Util::apply_all_roles($instance, ('MyApp::SomeRole'));
322
323 Or you can use the role's meta object:
324
325 MyApp::SomeRole->meta->apply($instance);
326
327 The mutable/immutable state is not relevant to roles applied to
328 instances. See Moose::Role and Moose::Util for more details and
329 Moose::Cookbook::Roles::Recipe3 for a more developed example.
330
332 Sometimes you may want to add a role to an object instance, rather than
333 to a class. For example, you may want to add debug tracing to one
334 instance of an object while debugging a particular bug. Another use
335 case might be to dynamically change objects based on a user's
336 configuration, as a plugin system.
337
338 The best way to do this is to use the "apply_all_roles" function from
339 Moose::Util:
340
341 use Moose::Util qw( apply_all_roles );
342
343 my $car = Car->new;
344 apply_all_roles( $car, 'Breakable' );
345
346 This function can apply more than one role at a time, and will do so
347 using the normal Moose role combination system. We recommend using this
348 function to apply roles to an object. This is what Moose uses
349 internally when you call "with".
350
352 Dave Rolsky <autarch@urth.org>
353
355 Copyright 2009 by Infinity Interactive, Inc.
356
357 <http://www.iinteractive.com>
358
359 This library is free software; you can redistribute it and/or modify it
360 under the same terms as Perl itself.
361
362
363
364perl v5.12.2 2010-08-20 Moose::Manual::Roles(3)