5 Moose::Manual::Roles - Roles, an Alternative to Deep Hierarchies and Base Classes
9 A role is something that classes do. Usually, a role encapsulates some
10 piece of behavior or state that can be shared between classes. It is
11 important to understand that I<roles are not classes>. Roles do not
12 participate in inheritance, and a role cannot be instantiated.
14 Instead, a role is I<composed> into a class. In practical terms, this
15 means that all of the methods and attributes defined in a role are
16 added directly to (we sometimes say ("flattened into") the class that
17 consumes the role. These attributes and methods then show up in the
18 class as if they were defined directly in the class.
20 Moose roles are similar to mixins or interfaces in other languages.
22 Besides defining their own methods and attributes, roles can also
23 require that the consuming class define certain methods of its
24 own. You could have a role that consisted only of a list of required
25 methods, in which case the role would be very much like a Java
30 Creating a role looks a lot like creating a Moose class:
49 Except for our use of C<Moose::Role>, this looks just like a class
50 definition with Moose. However, this is not a class, and it cannot be
53 Instead, its attributes and methods will be composed into classes
67 The C<with> function composes roles into a class. Once that is done,
68 the C<Car> class has an C<is_broken> attribute and a C<break>
69 method. The C<Car> class also C<does('Breakable')>:
71 my $car = Car->new( engine => Engine->new );
73 print $car->is_broken ? 'Still working' : 'Busted';
75 print $car->is_broken ? 'Still working' : 'Busted';
77 $car->does('Breakable'); # true
85 We could use this same role in a C<Bone> class:
98 =head1 REQUIRED METHODS
100 As mentioned previously, a role can require that consuming classes
101 provide one or more methods. Using our C<Breakable> example, let's
102 make it require that consuming classes implement their own C<break>
116 after 'break' => sub {
122 If we try to consume this role in a class that does not have a
123 C<break> method, we will get an exception.
125 Note that attribute-generated accessors do not satisfy the requirement
126 that the named method exists. Similarly, a method modifier does not
127 satisfy this requirement either. This may change in the future.
129 You can also see that we added a method modifier on
130 C<break>. Basically, we want consuming classes to implement their own
131 logic for breaking, but we make sure that the C<is_broken> attribute
132 is always set to true when C<break> is called.
148 if ( $self->is_moving ) {
153 =head1 USING METHOD MODIFIERS
155 Method modifiers and roles are a very powerful combination. Often, a
156 role will combine method modifiers and required methods. We already
157 saw one example with our C<Breakable> example.
159 Method modifiers increase the complexity of roles, because they make
160 the role application order relevant. If a class uses multiple roles,
161 each of which modify the same method, those modifiers will be applied
162 in the same order as the roles are used:
170 with 'Breakable', 'ExplodesOnBreakage';
172 Assuming that the new C<ExplodesOnBreakage> method I<also> has an
173 C<after> modifier on C<break>, the C<after> modifiers will run one
174 after the other. The modifier from C<Breakable> will run first, then
175 the one from C<ExplodesOnBreakage>.
177 =head1 METHOD CONFLICTS
179 If a class composes multiple roles, and those roles have methods of
180 the same name, we will have a conflict. In that case, the composing
181 class is required to provide its I<own> method of the same name.
191 If we compose both C<Breakable> and C<Breakdancer> in a class, we must
192 provide our own C<break> method:
194 package FragileDancer;
198 with 'Breakable', 'Breakdancer';
202 =head1 METHOD EXCLUSION AND ALIASING
204 If we want our C<FragileDancer> class to be able to call the methods
205 from both its roles, we can alias the methods:
207 package FragileDancer;
211 with 'Breakable' => { alias => { break => 'break_bone' } },
212 'Breakdancer' => { alias => { break => 'break_dance' } };
214 However, aliasing a method simply makes a I<copy> of the method with
215 the new name. We also need to exclude the original name:
217 with 'Breakable' => {
218 alias => { break => 'break_bone' },
222 alias => { break => 'break_dance' },
226 The exclude parameter prevents the C<break> method from being composed
227 into the C<FragileDancer> class, so we don't have a conflict. This
228 means that C<FragileDancer> does not need to implement its own
231 This is useful, but it's worth noting that this breaks the contract
232 implicit in consuming a role. Our C<FragileDancer> class does both the
233 C<Breakable> and C<BreakDancer>, but does not provide a C<break>
234 method. If some API expects an object that does one of those roles, it
235 probably expects it to implement that method.
239 Dave Rolsky E<lt>autarch@urth.orgE<gt>
241 =head1 COPYRIGHT AND LICENSE
243 Copyright 2009 by Infinity Interactive, Inc.
245 L<http://www.iinteractive.com>
247 This library is free software; you can redistribute it and/or modify
248 it under the same terms as Perl itself.