1MooseX::Role::ParameterUiszeerd:C:oTnuttroirbiuatle(d3M)PoeorsleXD:o:cRuomleen:t:aPtairoanmeterized::Tutorial(3)
2
3
4

NAME

6       MooseX::Role::Parameterized::Tutorial - why and how
7

VERSION

9       version 1.11
10

MOTIVATION

12       Roles are composable units of behavior. They are useful for factoring
13       out functionality common to many classes from any part of your class
14       hierarchy. See Moose::Cookbook::Roles::Comparable_CodeReuse for an
15       introduction to Moose::Role.
16
17       While combining roles affords you a great deal of flexibility,
18       individual roles have very little in the way of configurability. Core
19       Moose provides "-alias" for renaming methods and "-excludes" for
20       ignoring methods. These options are primarily for resolving role
21       conflicts. Depending on how much of a purist you are, these options are
22       solely for resolving role conflicts. See
23       Moose::Cookbook::Roles::Restartable_AdvancedComposition for more about
24       "-alias" and "-excludes".
25
26       Because roles serve many different masters, they usually provide only
27       the least common denominator of functionality. To empower roles
28       further, more configurability than "-alias" and "-excludes" is
29       required. Perhaps your role needs to know which method to call when it
30       is done processing. Or what default value to use for its "url"
31       attribute.
32
33       Parameterized roles offer a solution to these (and other) kinds of
34       problems.
35

USAGE

37   "with"
38       The syntax of a class consuming a parameterized role has not changed
39       from the standard "with". You pass in parameters just like you pass in
40       "-alias" and "-excludes" to ordinary roles (though your custom
41       parameters do not get hyphens, since these are not core Moose
42       composition parameters):
43
44           with 'MyRole::InstrumentMethod' => {
45               method_name => 'dbh_do',
46               log_to      => 'query.log',
47           };
48
49       You can still combine parameterized roles. You just need to specify
50       parameters immediately after the role they belong to:
51
52           with (
53               'My::Parameterized::Role' => {
54                   needs_better_example => 1,
55               },
56               'My::Other::Role',
57           );
58
59       We, like Moose itself, use Data::OptList to make sure that a list of
60       role names and associated parameters is handled correctly.
61
62   "parameter"
63       Inside your parameterized role, you specify a set of parameters. This
64       is exactly like specifying the attributes of a class. Instead of "has"
65       in Moose you use the keyword "parameter", but your parameters can use
66       any options to "has".
67
68           parameter 'delegation' => (
69               isa       => 'HashRef|ArrayRef|RegexpRef',
70               predicate => 'has_delegation',
71           );
72
73       You do have to declare what parameters you accept, just like you have
74       to declare what attributes you accept for regular Moose objects.
75
76       One departure from "has" is that we create a reader accessor for you by
77       default. In other words, we assume "is => 'ro'". We create this reader
78       for convenience because generally the parameterized role is the only
79       consumer of the parameters object, so data hiding is not as important
80       than in the general case of "has" in Moose. If you do not want an
81       accessor, you can use "is => 'bare'".
82
83   "role"
84       "role" takes a block of code that will be used to generate your role
85       with its parameters bound. Here is where you declare components that
86       depend on parameters. You can declare attributes, methods, modifiers,
87       etc. The first argument to the "role" is an object containing the
88       parameters specified by "with". You can access the parameters just like
89       regular attributes on that object.
90
91       Each time you compose this parameterized role, the "role {}" block will
92       be executed. It will receive a new parameter object and produce an
93       entirely new role. That's the whole point, after all.
94
95       Due to limitations inherent in Perl, you must declare methods with
96       "method name => sub { ... }" instead of the usual "sub name { ... }".
97       Your methods may, of course, close over the parameter object. This
98       means that your methods may use parameters however they wish!
99

USES

101       Ideally these will become fully-explained examples in something
102       resembling Moose::Cookbook. But for now, only a brain dump.
103
104       Configure a role's attributes
105           You can rename methods with core Moose, but now you can rename
106           attributes. You can now also choose type, default value, whether
107           it's required, traits, etc.
108
109               parameter traits => (
110                   isa     => 'ArrayRef',
111                   default => sub { [] },
112               );
113
114               parameter type => (
115                   isa     => 'Str',
116                   default => 'Any',
117               );
118
119               role {
120                   my $p = shift;
121
122                   has action => (
123                       traits => $p->traits,
124                       isa    => $p->type,
125                       ...
126                   );
127               };
128
129       Inform a role of your class' attributes and methods
130           Core roles can only require methods with specific names chosen by
131           the role. Now your roles can demand that the class specifies a
132           method name you wish the role to instrument, or which attributes to
133           dump to a file.
134
135               parameter instrument_method => (
136                   isa      => 'Str',
137                   required => 1,
138               );
139
140               role {
141                   my $p = shift;
142                   around $p->instrument_method => sub { ... };
143               };
144
145       Arbitrary execution choices
146           Your role may be able to provide configuration in how the role's
147           methods operate. For example, you can tell the role whether to save
148           intermediate states.
149
150               parameter save_intermediate => (
151                   isa     => 'Bool',
152                   default => 0,
153               );
154
155               role {
156                   my $p = shift;
157                   method process => sub {
158                       ...
159                       if ($p->save_intermediate) { ... }
160                       ...
161                   };
162               };
163
164       Deciding a backend
165           Your role may be able to freeze and thaw your instances using YAML,
166           JSON, Storable. Which backend to use can be a parameter.
167
168               parameter format => (
169                   isa     => (enum ['Storable', 'YAML', 'JSON']),
170                   default => 'Storable',
171               );
172
173               role {
174                   my $p = shift;
175                   if ($p->format eq 'Storable') {
176                       method freeze => \&Storable::freeze;
177                       method thaw   => \&Storable::thaw;
178                   }
179                   elsif ($p->format eq 'YAML') {
180                       method freeze => \&YAML::Dump;
181                       method thaw   => \&YAML::Load;
182                   }
183                   ...
184               };
185
186       Additional validation
187           Ordinary roles can require that its consumers have a particular
188           list of method names. Since parameterized roles have direct access
189           to its consumer, you can inspect it and throw errors if the
190           consumer does not meet your needs.
191
192               role {
193                   my $p    = shift;
194                   my %args = @_;
195                   my $consumer = $args{consumer};
196
197                   $consumer->find_attribute_by_name('stack')
198                       or confess "You must have a 'stack' attribute";
199
200                   my $push = $consumer->find_method_by_name('push')
201                       or confess "You must have a 'push' method";
202
203                   my $params = $push->parsed_signature->positional_params->params;
204                   @$params == 1
205                       or confess "Your push method must take a single parameter";
206
207                   $params->[0]->sigil eq '$'
208                       or confess "Your push parameter must be a scalar";
209
210                   ...
211               };
212

SUPPORT

214       Bugs may be submitted through the RT bug tracker
215       <https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Role-
216       Parameterized> (or bug-MooseX-Role-Parameterized@rt.cpan.org
217       <mailto:bug-MooseX-Role-Parameterized@rt.cpan.org>).
218
219       There is also a mailing list available for users of this distribution,
220       at <http://lists.perl.org/list/moose.html>.
221
222       There is also an irc channel available for users of this distribution,
223       at "#moose" on "irc.perl.org" <irc://irc.perl.org/#moose>.
224

AUTHOR

226       Shawn M Moore <code@sartak.org>
227
229       This software is copyright (c) 2008 by Shawn M Moore.
230
231       This is free software; you can redistribute it and/or modify it under
232       the same terms as the Perl 5 programming language system itself.
233
234
235
236perl v5.32.0                      2020-M0o7o-s2e8X::Role::Parameterized::Tutorial(3)
Impressum