1Role::Basic(3pm) User Contributed Perl Documentation Role::Basic(3pm)
2
3
4
6 Role::Basic - Just roles. Nothing else.
7
9 Version 0.13
10
12 In a role:
13
14 package Does::Serialize::AsYAML;
15 use Role::Basic;
16 use YAML::Syck;
17 requires 'as_hash';
18
19 sub serialize {
20 my $self = shift;
21 return Dump( $self->as_hash );
22 }
23
24 1;
25
26 In your class:
27
28 package My::Class;
29 use Role::Basic 'with';
30
31 with qw(
32 Does::Serialize::AsYAML
33 );
34
35 sub as_hash { ... } # because the role requires it
36
38 This code appears to be stable and currently passes over 300 tests.
39 We've not (yet) heard of any bugs. There are no functional changes with
40 this release. It's merely here to let early-adopters know it's safe to
41 give it a spin.
42
44 For an extended discussion, see
45 <http://blogs.perl.org/users/ovid/2010/12/rolebasic---when-you-only-want-roles.html>.
46
47 Sometimes you want roles. You're not sure about Moose, Mouse, Moo and
48 what was that damned Squirrel thing anyway? Then there's Class::Trait,
49 but it has a funky syntax and the maintainer's deprecated it in favor
50 of Moose::Role and you really don't care that it handles overloading,
51 instance application or has a workaround for the SUPER:: bug. You
52 think a meta-object protocol sounds nifty, but you don't understand it.
53 Maybe you're not sure you want the syntactic sugar for object
54 declaration. Maybe you've convinced your colleagues that roles are a
55 good idea but they're leery of dragging in Moose (your author has had
56 this happen more than once and heard of others making the same
57 complaint). Sometimes you just want good old-fashioned roles which let
58 you separate class responsibility from code reuse.
59
60 Whatever your reasons, this is the module you're looking for. It only
61 provides roles and its major design goals are safety and simplicity.
62 It also aims to be a subset of Moose::Role behavior so that when/if
63 you're ready to upgrade, there will be minimal pain.
64
66 To declare the current package as a role, simply add the following line
67 to the package:
68
69 use Role::Basic;
70
71 You can then use "with" to consume other roles and "requires" to list
72 the methods this role requires. Note that the only methods the role
73 will provide are methods declared directly in the role or consumed from
74 other roles. Thus:
75
76 package My::Role;
77 use Role::Basic;
78 use List::Util 'sum'; # this will not be provided by the role
79 with 'Some::Other::Role'; # any methods from this role will be provided
80
81 sub some_method {...} # this will be provided by the role
82
83 Allowed methods in roles
84 Warning: this functionality is experimental and is subject to change
85 with no warning.
86
87 As mentioned, methods imported into a role are not provided by that
88 role. However, this can make it very hard when you want to provide
89 simple getters/setters. To get around this limitation, a role (and only
90 roles, not classes) may specify one class which they 'allow' to provide
91 additional methods:
92
93 package My::Role;
94 use Role::Basic allow => 'Class::BuildMethods';
95 use Class::BuildMethods qw/foo bar/;
96
97 # your role will now provide foo and bar methods
98 # rest of role definition here
99
100 Please note that if you do this, the code which provides these 'extra'
101 methods should not provide them in a way which is incompatible with
102 your objects. For example, many getter/setters generation classes
103 assume you're using a blessed hashref. Most objects are, but the role
104 should not make such an assumption about the class which consumes it.
105 In the above example, we use Class::BuildMethods. It's agnostic about
106 your object implementation, but it's slow.
107
108 See <http://blogs.perl.org/users/ovid/2011/01/happy-new-yearroles.html>
109 and search for 'glue' to understand why this is important.
110
112 To declare the current package as a class that will use roles, simply
113 add the following line to the package:
114
115 use Role::Basic 'with';
116
117 Just as with Moose, you can have "-alias", "-excludes", and "-version".
118
119 Unlike Moose, we also provide a "-rename" target. It combines "-alias"
120 and "-excludes". This code:
121
122 package My::Class;
123 use Role::Basic 'with';
124
125 with 'My::Role' => {
126 -rename => { foo => 'baz', bar => 'gorch' },
127 };
128
129 Is identical to this code:
130
131 package My::Class;
132 use Role::Basic 'with';
133
134 with 'My::Role' => {
135 -alias => { foo => 'baz', bar => 'gorch' },
136 -excludes => [qw/foo bar/],
137 };
138
140 Both roles and classes will receive the following methods:
141
142 • "with"
143
144 "with" accepts a list and may only be called once per role or
145 class. This is because calling it multiple times removes
146 composition safety. Just as with Moose::Role, any class may also
147 have "-alias" or "-excludes".
148
149 package My::Class;
150 use Role::Basic 'with';
151
152 with 'Does::Serialize::AsYAML' => { -alias => { serialize => 'as_yaml' } };
153
154 And later:
155
156 print $object->as_yaml;
157
158 • "DOES"
159
160 Returns true if the class or role consumes a role of the given
161 name:
162
163 if ( $class->DOES('Does::Serialize::AsYAML') ) {
164 ...
165 }
166
167 Every role "DOES" itself.
168
169 Further, if you're a role, you can also specify methods you require:
170
171 • "requires"
172
173 package Some::Role;
174 use Role::Basic;
175
176 # roles can consume other roles
177 with 'Another::Role';
178
179 requires qw(
180 first_method
181 second_method
182 another_method
183 );
184
185 In the example above, if "Another::Role" has methods it requires,
186 they will be added to the requirements of "Some::Role".
187
189 There are two overriding design goals for "Role::Basic": simplicity and
190 safety. We make it a bit harder to shoot yourself in the foot and we
191 aim to keep the code as simple as possible. Feature requests are
192 welcomed, but will not be acted upon if they violate either of these
193 two design goals.
194
195 Thus, if you need something which "Role::Basic" does not support,
196 you're strongly encouraged to consider Moose or Mouse.
197
198 The following list details the outcomes of this module's goals.
199
200 • Basic role support
201
202 This includes composing into your class, composing roles from other
203 roles, roles declaring requirements and conflict resolution.
204
205 • Moose-like syntax
206
207 To ease migration difficulties, we use a Moose-like syntax. If you
208 wish to upgrade to Moose later, or you find that others on your
209 project are already familiar with Moose, this should make
210 "Role::Basic" easier to learn.
211
212 • No handling of SUPER:: bug
213
214 A well-known bug in OO Perl is that a SUPER:: method is invoked
215 against the class its declared in, not against the class of the
216 invocant. Handling this properly generally involves eval'ing a
217 method directly into the correct package:
218
219 eval <<"END_METHOD";
220 package $some_package;
221
222 sub some_method { ... }
223 END_METHOD
224
225 Or using a different method resolution order (MRO) such as with
226 Class::C3 or friends. We alert you to this limitation but make no
227 attempt to address it. We consider this a feature because roles
228 should not know or care how they are composed and probably should
229 not know if a superclass exists. This helps to keep this module
230 simple, a primary design goal.
231
232 • Composition Safety
233
234 In addition to the normal conflict resolution, only one "with"
235 statement is allowed:
236
237 package Foo;
238 use Role::Basic;
239 with 'Some::Role';
240 with 'Another::Role'; # boom!
241
242 This is because when you have more than one "with" statement, the
243 latter will ignore conflicts with the first. We could work around
244 this, but this would be significantly different from the behavior
245 of Moose.
246
247 • Override Safety
248
249 By default, we aim to behave like Moose::Role. This means that if
250 a class consuming a role has a method with the same name the role
251 provides, the class silently wins. This has been a somewhat
252 contentious issue in the "Moose" community and the "silent"
253 behaviour has won. However, there are those who prefer that they
254 don't have their methods silently ignored. We provide two optional
255 environment variables to handle this:
256
257 $ENV{PERL_ROLE_OVERRIDE_WARN}
258 $ENV{PERL_ROLE_OVERRIDE_DIE}
259
260 If you prefer, you can set one of those to true and a class
261 overridding a role's method will "warn" or "die", as appropriate.
262 As you might expect, you can handle this with normal role behaviour
263 or exclusion or aliasing.
264
265 package My::Class;
266 use Role::Basic 'with';
267 with 'My::Role' => { -excludes => 'conflicting_method' };
268
269 From your author's email exchanges with the authors of the original
270 traits paper (referenced here with permission), the "class silently
271 wins" behaviour was not intended. About this, Dr. Andrew P. Black
272 wrote the following:
273
274 Yes, it is really important that a programmer can see clearly when a trait
275 method is being overridden -- just as it is important that it is clear
276 when an inherited method is being overridden.
277
278 In Smalltalk, where a program is viewed as a graph of objects, the obvious
279 solution to this problem is to provide an adequate tool to show the
280 programmer interesting properties of the program. The original traits
281 browser did this for Smalltalk; the reason that we implemented it is that
282 traits were really NOT a good idea (that is,they were not very usable or
283 maintainable) without it. Since then, the same sort of "virtual
284 protocols" have been built into the browser for other properties, like
285 "overridden methods".
286
287 Note that those are provided as environment variables and not as
288 syntax in the code itself to help keep the code closer to the Moose
289 syntax.
290
291 • No instance application
292
293 "Role::Basic" does not support applying roles to object instances.
294 This may change in the future.
295
296 • No method modifiers
297
298 These have been especially problematic. Consider a "before"
299 modifier which multiplies a value by 2 and another before modifier
300 which divides a value by 3. The order in which those modifiers are
301 applied becomes extremely important. and role-consumption is no
302 longer entirely declarative, but becomes partially procedural. This
303 causes enough problems that on Sep 14, 2010 on the Moose mailing
304 list, Stevan Little wrote:
305
306 I totally agree [with the described application order problems], and if I
307 had to do it over again, I would not have allowed method modifiers in
308 roles. They ruin the unordered-ness of roles and bring about edge cases
309 like this that are not so easily solved.
310
311 Thus, "Role::Basic" does not and will not support method modifiers.
312 If you need them, consider Moose.
313
315 Curtis 'Ovid' Poe, "<ovid at cpan.org>"
316
318 Please report any bugs or feature requests to "bug-role-basic at
319 rt.cpan.org", or through the web interface at
320 <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Role-Basic>. I will be
321 notified, and then you'll automatically be notified of progress on your
322 bug as I make changes.
323
325 You can find documentation for this module with the perldoc command.
326
327 perldoc Role::Basic
328
329 You can also look for information at:
330
331 • RT: CPAN's request tracker
332
333 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Role-Basic>
334
335 • AnnoCPAN: Annotated CPAN documentation
336
337 <http://annocpan.org/dist/Role-Basic>
338
339 • CPAN Ratings
340
341 <http://cpanratings.perl.org/d/Role-Basic>
342
343 • Search CPAN
344
345 <http://search.cpan.org/dist/Role-Basic/>
346
348 • Role::Tiny
349
350 • Moose::Role
351
352 • Mouse::Role
353
355 Copyright 2010 Curtis 'Ovid' Poe.
356
357 This program is free software; you can redistribute it and/or modify it
358 under the terms of either: the GNU General Public License as published
359 by the Free Software Foundation; or the Artistic License.
360
361 See http://dev.perl.org/licenses/ for more information.
362
363
364
365perl v5.38.0 2023-07-21 Role::Basic(3pm)