Commit | Line | Data |
24a8fe99 |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
6 | Moose::Spec::Role - Formal spec for Role behavior |
7 | |
8 | =head1 DESCRIPTION |
9 | |
004222dc |
10 | B<NOTE:> This document is currently incomplete. |
11 | |
24a8fe99 |
12 | =head2 Components of a Role |
13 | |
14 | =over 4 |
15 | |
16 | =item Excluded Roles |
17 | |
d03bd989 |
18 | A role can have a list of excluded roles, these are basically |
19 | roles that they shouldn't be composed with. This is not just |
20 | direct composition either, but also "inherited" composition. |
709c321c |
21 | |
d03bd989 |
22 | This feature was taken from the Fortress language and is really |
709c321c |
23 | of most use when building a large set of role "building blocks" |
24 | some of which should never be used together. |
25 | |
24a8fe99 |
26 | =item Attributes |
27 | |
d03bd989 |
28 | A roles attributes are similar to those of a class, except that |
709c321c |
29 | they are not actually applied. This means that methods that are |
30 | generated by an attributes accessor will not be generated in the |
31 | role, but only created once the role is applied to a class. |
32 | |
24a8fe99 |
33 | =item Methods |
34 | |
709c321c |
35 | These are the methods defined within the role. Simple as that. |
36 | |
24a8fe99 |
37 | =item Required Methods |
38 | |
d03bd989 |
39 | A role can require a consuming class (or role) to provide a |
40 | given method. Failure to do so for classes is a fatal error, |
41 | while for roles it simply passes on the method requirement to |
709c321c |
42 | the consuming role. |
43 | |
44 | =item Required Attributes |
45 | |
46 | Just as a role can require methods, it can also require attributes. |
d03bd989 |
47 | The requirement fulfilling attribute must implement at least as much |
709c321c |
48 | as is required. That means, for instance, that if the role requires |
6549b0d1 |
49 | that the attribute be read-only, then it must at least have a reader |
d03bd989 |
50 | and can also have a writer. It means that if the role requires that |
51 | the attribute be an ArrayRef, then it must either be an ArrayRef or |
709c321c |
52 | a subtype of an ArrayRef. |
53 | |
6549b0d1 |
54 | =item Overridden Methods |
24a8fe99 |
55 | |
d03bd989 |
56 | The C<override> and C<super> keywords are allowed in roles, but |
57 | their behavior is different from that of it's class counterparts. |
58 | The C<super> in a class refers directly to that class's superclass, |
24a8fe99 |
59 | while the C<super> in a role is deferred and only has meaning once |
d03bd989 |
60 | the role is composed into a class. Once that composition occurs, |
61 | C<super> then refers to that class's superclass. |
24a8fe99 |
62 | |
d03bd989 |
63 | It is key to remember that roles do not have hierarchy, so they |
24a8fe99 |
64 | can never have a I<super> role. |
65 | |
66 | =item Method Modifiers |
67 | |
d03bd989 |
68 | These are the C<before>, C<around> and C<after> modifiers provided |
69 | in Moose classes. The difference here is that the modifiers are not |
70 | actually applied until the role is composed into a class (this is |
709c321c |
71 | just like attributes and the C<override> keyword). |
72 | |
24a8fe99 |
73 | =back |
74 | |
709c321c |
75 | =head2 Role Composition |
76 | |
3e19778d |
77 | =head3 Composing into a Class |
709c321c |
78 | |
79 | =over 4 |
80 | |
81 | =item Excluded Roles |
82 | |
83 | =item Required Methods |
84 | |
85 | =item Required Attributes |
86 | |
87 | =item Attributes |
88 | |
89 | =item Methods |
90 | |
6549b0d1 |
91 | =item Overridden methods |
709c321c |
92 | |
93 | =item Method Modifiers (before, around, after) |
94 | |
95 | =back |
24a8fe99 |
96 | |
3e19778d |
97 | =head3 Composing into a Instance |
98 | |
d03bd989 |
99 | =head3 Composing into a Role |
24a8fe99 |
100 | |
101 | =over 4 |
102 | |
709c321c |
103 | =item Excluded Roles |
104 | |
105 | =item Required Methods |
106 | |
107 | =item Required Attributes |
108 | |
109 | =item Attributes |
110 | |
111 | =item Methods |
112 | |
6549b0d1 |
113 | =item Overridden methods |
709c321c |
114 | |
115 | =item Method Modifiers (before, around, after) |
116 | |
117 | =back |
118 | |
3e19778d |
119 | =head3 Role Summation |
709c321c |
120 | |
d03bd989 |
121 | When multiple roles are added to another role (using the |
122 | C<with @roles> keyword) the roles are composed symmetrically. |
123 | The product of the composition is a composite role |
709c321c |
124 | (L<Moose::Meta::Role::Composite>). |
125 | |
126 | =over 4 |
127 | |
128 | =item Excluded Roles |
129 | |
130 | =item Required Methods |
131 | |
132 | =item Required Attributes |
133 | |
24a8fe99 |
134 | =item Attributes |
135 | |
136 | Attributes with the same name will conflict and are considered |
d03bd989 |
137 | a unrecoverable error. No other aspect of the attribute is |
138 | examined, it is enough that just the attribute names conflict. |
24a8fe99 |
139 | |
d03bd989 |
140 | The reason for such early and harsh conflicts with attributes |
141 | is because there is so much room for variance between two |
142 | attributes that the problem quickly explodes and rules get |
143 | very complex. It is my opinion that this complexity is not |
24a8fe99 |
144 | worth the trouble. |
145 | |
146 | =item Methods |
147 | |
d03bd989 |
148 | Methods with the same name will conflict, but no error is |
149 | thrown, instead the method name is added to the list of |
24a8fe99 |
150 | I<required> methods for the new composite role. |
151 | |
d03bd989 |
152 | To look at this in terms of set theory, each role can be |
153 | said to have a set of methods. The symmetric difference of |
154 | these two sets is the new set of methods for the composite |
155 | role, while the intersection of these two sets are the |
24a8fe99 |
156 | conflicts. This can be illustrated like so: |
157 | |
158 | Role A has method set { a, b, c } |
159 | Role B has method set { c, d, e } |
d03bd989 |
160 | |
161 | The composite role (A,B) has |
24a8fe99 |
162 | method set { a, b, d, e } |
163 | conflict set { c } |
164 | |
6549b0d1 |
165 | =item Overridden methods |
24a8fe99 |
166 | |
d03bd989 |
167 | An overridden method can conflict in one of two ways. |
24a8fe99 |
168 | |
d03bd989 |
169 | The first way is with another overridden method of the same |
170 | name, and this is considered an unrecoverable error. This |
24a8fe99 |
171 | is an obvious error since you cannot override a method twice |
d03bd989 |
172 | in the same class. |
24a8fe99 |
173 | |
d03bd989 |
174 | The second way for conflict is for an overridden method and a |
175 | regular method to have the same name. This is also an unrecoverable |
176 | error since there is no way to combine these two, nor is it |
177 | okay for both items to be composed into a single class at some |
178 | point. |
24a8fe99 |
179 | |
180 | The use of override in roles can be tricky, but if used |
181 | carefully they can be a very powerful tool. |
182 | |
183 | =item Method Modifiers (before, around, after) |
184 | |
d03bd989 |
185 | Method modifiers are the only place where the ordering of |
186 | role composition matters. This is due to the nature of |
187 | method modifiers themselves. |
24a8fe99 |
188 | |
d03bd989 |
189 | Since a method can have multiple method modifiers, these |
190 | are just collected in order to be later applied to the |
24a8fe99 |
191 | class in that same order. |
192 | |
d03bd989 |
193 | In general, great care should be taken in using method |
194 | modifiers in roles. The order sensitivity can possibly |
195 | lead to subtle and difficult to find bugs if they are |
196 | overused. As with all good things in life, moderation |
24a8fe99 |
197 | is the key. |
198 | |
199 | =back |
200 | |
3e19778d |
201 | =head3 Composition Edge Cases |
202 | |
d03bd989 |
203 | This is a just a set of complex edge cases which can easily get |
204 | confused. This attempts to clarify those cases and provide an |
6549b0d1 |
205 | explanation of what is going on in them. |
3e19778d |
206 | |
207 | =over 4 |
208 | |
209 | =item Role Method Overriding |
210 | |
211 | Many people want to "override" methods in roles they are consuming. |
212 | This works fine for classes, since the local class method is favored |
d03bd989 |
213 | over the role method. However in roles it is trickier, this is because |
214 | conflicts result in neither method being chosen and the method being |
215 | "required" instead. |
3e19778d |
216 | |
217 | Here is an example of this (incorrect) type of overriding. |
218 | |
219 | package Role::Foo; |
220 | use Moose::Role; |
221 | |
222 | sub foo { ... } |
223 | |
224 | package Role::FooBar; |
225 | use Moose::Role; |
226 | |
227 | with 'Role::Foo'; |
228 | |
229 | sub foo { ... } |
230 | sub bar { ... } |
231 | |
d03bd989 |
232 | Here the C<foo> methods conflict and the Role::FooBar now requires a |
3e19778d |
233 | class or role consuming it to implement C<foo>. This is very often not |
234 | what the user wants. |
235 | |
236 | Now here is an example of the (correct) type of overriding, only it is |
237 | not overriding at all, as is explained in the text below. |
238 | |
239 | package Role::Foo; |
240 | use Moose::Role; |
241 | |
242 | sub foo { ... } |
243 | |
244 | package Role::Bar; |
245 | use Moose::Role; |
246 | |
247 | sub foo { ... } |
248 | sub bar { ... } |
249 | |
250 | package Role::FooBar; |
251 | use Moose::Role; |
252 | |
253 | with 'Role::Foo', 'Role::Bar'; |
d03bd989 |
254 | |
3e19778d |
255 | sub foo { ... } |
256 | |
257 | This works because the combination of Role::Foo and Role::Bar produce |
d03bd989 |
258 | a conflict with the C<foo> method. This conflict results in the |
259 | composite role (that was created by the combination of Role::Foo |
260 | and Role::Bar using the I<with> keyword) having a method requirement |
261 | of C<foo>. The Role::FooBar then fulfills this requirement. |
3e19778d |
262 | |
d03bd989 |
263 | It is important to note that Role::FooBar is simply fulfilling the |
264 | required C<foo> method, and **NOT** overriding C<foo>. This is an |
3e19778d |
265 | important distinction to make. |
266 | |
d03bd989 |
267 | Now here is another example of a (correct) type of overriding, this |
004222dc |
268 | time using the I<excludes> option. |
269 | |
270 | package Role::Foo; |
271 | use Moose::Role; |
d03bd989 |
272 | |
004222dc |
273 | sub foo { ... } |
d03bd989 |
274 | |
004222dc |
275 | package Role::FooBar; |
276 | use Moose::Role; |
d03bd989 |
277 | |
004222dc |
278 | with 'Role::Foo' => { excludes => 'foo' }; |
d03bd989 |
279 | |
004222dc |
280 | sub foo { ... } |
281 | sub bar { ... } |
282 | |
d03bd989 |
283 | By specifically excluding the C<foo> method during composition, |
004222dc |
284 | we allow B<Role::FooBar> to define it's own version of C<foo>. |
285 | |
3e19778d |
286 | =back |
287 | |
24a8fe99 |
288 | =head1 SEE ALSO |
289 | |
290 | =over 4 |
291 | |
292 | =item Traits |
293 | |
d03bd989 |
294 | Roles are based on Traits, which originated in the Smalltalk |
295 | community. |
24a8fe99 |
296 | |
d03bd989 |
297 | =over 4 |
24a8fe99 |
298 | |
299 | =item L<http://www.iam.unibe.ch/~scg/Research/Traits/> |
300 | |
301 | This is the main site for the original Traits papers. |
302 | |
303 | =item L<Class::Trait> |
304 | |
d03bd989 |
305 | I created this implementation of traits several years ago, |
306 | after reading the papers linked above. (This module is now |
6549b0d1 |
307 | maintained by Ovid and I am no longer involved with it). |
24a8fe99 |
308 | |
309 | =back |
310 | |
311 | =item Roles |
312 | |
d03bd989 |
313 | Since they are relatively new, and the Moose implementation |
24a8fe99 |
314 | is probably the most mature out there, roles don't have much |
315 | to link to. However, here is some bits worth looking at (mostly |
316 | related to Perl 6) |
317 | |
318 | =over 4 |
319 | |
320 | =item L<http://www.oreillynet.com/onlamp/blog/2006/08/roles_composable_units_of_obje.html> |
321 | |
d03bd989 |
322 | This is chromatic's take on roles, which is worth reading since |
24a8fe99 |
323 | he was/is one of the big proponents of them. |
324 | |
325 | =item L<http://svn.perl.org/perl6/doc/trunk/design/syn/S12.pod> |
326 | |
327 | This is Synopsis 12, which is all about the Perl 6 Object System. |
328 | Which, of course, includes roles. |
329 | |
330 | =back |
331 | |
332 | =back |
333 | |
334 | =head1 AUTHOR |
335 | |
336 | Stevan Little E<lt>stevan@iinteractive.comE<gt> |
337 | |
338 | =head1 COPYRIGHT AND LICENSE |
339 | |
2840a3b2 |
340 | Copyright 2007-2009 by Infinity Interactive, Inc. |
24a8fe99 |
341 | |
342 | L<http://www.iinteractive.com> |
343 | |
344 | This library is free software; you can redistribute it and/or modify |
345 | it under the same terms as Perl itself. |
346 | |
347 | =cut |
348 | |