Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / MooseX::Role::Parameterized::Tutorial.3pm
1 .\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10)
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sp \" Vertical space (when we can't use .PP)
6 .if t .sp .5v
7 .if n .sp
8 ..
9 .de Vb \" Begin verbatim text
10 .ft CW
11 .nf
12 .ne \\$1
13 ..
14 .de Ve \" End verbatim text
15 .ft R
16 .fi
17 ..
18 .\" Set up some character translations and predefined strings.  \*(-- will
19 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
21 .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
22 .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
23 .\" nothing in troff, for use with C<>.
24 .tr \(*W-
25 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 .ie n \{\
27 .    ds -- \(*W-
28 .    ds PI pi
29 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
31 .    ds L" ""
32 .    ds R" ""
33 .    ds C` ""
34 .    ds C' ""
35 'br\}
36 .el\{\
37 .    ds -- \|\(em\|
38 .    ds PI \(*p
39 .    ds L" ``
40 .    ds R" ''
41 'br\}
42 .\"
43 .\" Escape single quotes in literal strings from groff's Unicode transform.
44 .ie \n(.g .ds Aq \(aq
45 .el       .ds Aq '
46 .\"
47 .\" If the F register is turned on, we'll generate index entries on stderr for
48 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
49 .\" entries marked with X<> in POD.  Of course, you'll have to process the
50 .\" output yourself in some meaningful fashion.
51 .ie \nF \{\
52 .    de IX
53 .    tm Index:\\$1\t\\n%\t"\\$2"
54 ..
55 .    nr % 0
56 .    rr F
57 .\}
58 .el \{\
59 .    de IX
60 ..
61 .\}
62 .\"
63 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
64 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
65 .    \" fudge factors for nroff and troff
66 .if n \{\
67 .    ds #H 0
68 .    ds #V .8m
69 .    ds #F .3m
70 .    ds #[ \f1
71 .    ds #] \fP
72 .\}
73 .if t \{\
74 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
75 .    ds #V .6m
76 .    ds #F 0
77 .    ds #[ \&
78 .    ds #] \&
79 .\}
80 .    \" simple accents for nroff and troff
81 .if n \{\
82 .    ds ' \&
83 .    ds ` \&
84 .    ds ^ \&
85 .    ds , \&
86 .    ds ~ ~
87 .    ds /
88 .\}
89 .if t \{\
90 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
91 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
92 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
93 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
94 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
95 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
96 .\}
97 .    \" troff and (daisy-wheel) nroff accents
98 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
99 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
100 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
101 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
102 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
103 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
104 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
105 .ds ae a\h'-(\w'a'u*4/10)'e
106 .ds Ae A\h'-(\w'A'u*4/10)'E
107 .    \" corrections for vroff
108 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
109 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
110 .    \" for low resolution devices (crt and lpr)
111 .if \n(.H>23 .if \n(.V>19 \
112 \{\
113 .    ds : e
114 .    ds 8 ss
115 .    ds o a
116 .    ds d- d\h'-1'\(ga
117 .    ds D- D\h'-1'\(hy
118 .    ds th \o'bp'
119 .    ds Th \o'LP'
120 .    ds ae ae
121 .    ds Ae AE
122 .\}
123 .rm #[ #] #H #V #F C
124 .\" ========================================================================
125 .\"
126 .IX Title "MooseX::Role::Parameterized::Tutorial 3"
127 .TH MooseX::Role::Parameterized::Tutorial 3 "2009-08-22" "perl v5.8.7" "User Contributed Perl Documentation"
128 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
129 .\" way too many mistakes in technical documents.
130 .if n .ad l
131 .nh
132 .SH "NAME"
133 MooseX::Role::Parameterized::Tutorial \- why and how
134 .SH "MOTIVATION"
135 .IX Header "MOTIVATION"
136 Roles are composable units of behavior. They are useful for factoring out
137 functionality common to many classes from any part of your class hierarchy. See
138 Moose::Cookbook::Roles::Recipe1 for an introduction to Moose::Role.
139 .PP
140 While combining roles affords you a great deal of flexibility, individual roles
141 have very little in the way of configurability. Core Moose provides \f(CW\*(C`alias\*(C'\fR
142 for renaming methods and \f(CW\*(C`excludes\*(C'\fR for ignoring methods. These options are
143 primarily (perhaps solely) for disambiguating role conflicts. See
144 Moose::Cookbook::Roles::Recipe2 for more about \f(CW\*(C`alias\*(C'\fR and \f(CW\*(C`excludes\*(C'\fR.
145 .PP
146 Because roles serve many different masters, they usually provide only the least
147 common denominator of functionality. To empower roles further, more
148 configurability than \f(CW\*(C`alias\*(C'\fR and \f(CW\*(C`excludes\*(C'\fR is required. Perhaps your role
149 needs to know which method to call when it is done. Or what default value to
150 use for its \f(CW\*(C`url\*(C'\fR attribute.
151 .PP
152 Parameterized roles offer exactly this solution.
153 .SH "USAGE"
154 .IX Header "USAGE"
155 \fI\f(CI\*(C`with\*(C'\fI\fR
156 .IX Subsection "with"
157 .PP
158 The syntax of a class consuming a parameterized role has not changed from the
159 standard \f(CW\*(C`with\*(C'\fR. You pass in parameters just like you pass in \f(CW\*(C`alias\*(C'\fR and
160 \&\f(CW\*(C`excludes\*(C'\fR to ordinary roles:
161 .PP
162 .Vb 4
163 \&    with \*(AqMyRole::InstrumentMethod\*(Aq => {
164 \&        method_name => \*(Aqdbh_do\*(Aq,
165 \&        log_to      => \*(Aqquery.log\*(Aq,
166 \&    };
167 .Ve
168 .PP
169 You can still combine parameterized roles. You just need to specify parameters
170 immediately after the role they belong to:
171 .PP
172 .Vb 6
173 \&    with (
174 \&        \*(AqMy::Parameterized::Role\*(Aq => {
175 \&            needs_better_example => 1,
176 \&        },
177 \&        \*(AqMy::Other::Role\*(Aq,
178 \&    );
179 .Ve
180 .PP
181 \fI\f(CI\*(C`parameter\*(C'\fI\fR
182 .IX Subsection "parameter"
183 .PP
184 Inside your parameterized role, you specify a set of parameters. This is
185 exactly like specifying the attributes of a class. Instead of \f(CW\*(C`has\*(C'\fR you use
186 the keyword \f(CW\*(C`parameter\*(C'\fR, but your parameters can use any options to \f(CW\*(C`has\*(C'\fR.
187 .PP
188 .Vb 4
189 \&    parameter \*(Aqdelegation\*(Aq => (
190 \&        isa       => \*(AqHashRef|ArrayRef|RegexpRef\*(Aq,
191 \&        predicate => \*(Aqhas_delegation\*(Aq,
192 \&    );
193 .Ve
194 .PP
195 You do have to declare what parameters you accept, just like you have to
196 declare what attributes you accept for regular Moose objects.
197 .PP
198 \fI\f(CI\*(C`role\*(C'\fI\fR
199 .IX Subsection "role"
200 .PP
201 \&\f(CW\*(C`role\*(C'\fR takes a block of code that will be used to generate your role with its
202 parameters bound. Here is where you declare parameterized components: use
203 \&\f(CW\*(C`has\*(C'\fR, method modifiers, and so on. The \f(CW\*(C`role\*(C'\fR block receives an argument,
204 which contains the parameters specified by \f(CW\*(C`with\*(C'\fR. You can access the
205 parameters just like regular attributes on that object.
206 .PP
207 Each time you compose this parameterized role, the role {} block will be
208 executed. It will receive a new parameter object and produce an entirely new
209 role. That's the whole point, after all.
210 .PP
211 Due to limitations inherent in Perl, you must declare methods with
212 \&\f(CW\*(C`method name => sub { ... }\*(C'\fR instead of the usual \f(CW\*(C`sub name { ... }\*(C'\fR.
213 Your methods may, of course, close over the parameter object. This means that
214 your methods may use parameters however they wish!
215 .SH "USES"
216 .IX Header "USES"
217 Ideally these will become fully-explained examples in something resembling
218 Moose::Cookbook. But for now, only a braindump.
219 .IP "Configure a role's attributes" 4
220 .IX Item "Configure a role's attributes"
221 You can rename methods with core Moose, but now you can rename attributes. You
222 can now also choose type, default value, whether it's required, \fBtraits\fR, etc.
223 .Sp
224 .Vb 4
225 \&    parameter traits => (
226 \&        isa     => \*(AqArrayRef\*(Aq,
227 \&        default => sub { [] },
228 \&    );
229 \&
230 \&    parameter type => (
231 \&        isa     => \*(AqStr\*(Aq,
232 \&        default => \*(AqAny\*(Aq,
233 \&    );
234 \&
235 \&    role {
236 \&        my $p = shift;
237 \&
238 \&        has action => (
239 \&            traits => $p\->traits,
240 \&            isa    => $p\->type,
241 \&            ...
242 \&        );
243 \&    }
244 .Ve
245 .IP "Inform a role of your class' attributes and methods" 4
246 .IX Item "Inform a role of your class' attributes and methods"
247 Core roles can require only methods with specific names. Now your roles can
248 require that you specify a method name you wish the role to instrument, or
249 which attributes to dump to a file.
250 .Sp
251 .Vb 4
252 \&    parameter instrument_method => (
253 \&        isa      => \*(AqStr\*(Aq,
254 \&        required => 1,
255 \&    );
256 \&
257 \&    role {
258 \&        my $p = shift;
259 \&        around $p\->instrument_method => sub { ... };
260 \&    }
261 .Ve
262 .IP "Arbitrary execution choices" 4
263 .IX Item "Arbitrary execution choices"
264 Your role may be able to provide configuration in how the role's methods
265 operate. For example, you can tell the role whether to save intermediate
266 states.
267 .Sp
268 .Vb 4
269 \&    parameter save_intermediate => (
270 \&        isa     => \*(AqBool\*(Aq,
271 \&        default => 0,
272 \&    );
273 \&
274 \&    role {
275 \&        my $p = shift;
276 \&        method process => sub {
277 \&            ...
278 \&            if ($p\->save_intermediate) { ... }
279 \&            ...
280 \&        };
281 \&    }
282 .Ve
283 .IP "Deciding a backend" 4
284 .IX Item "Deciding a backend"
285 Your role may be able to freeze and thaw your instances using \s-1YAML\s0, \s-1JSON\s0,
286 Storable. Which backend to use can be a parameter.
287 .Sp
288 .Vb 4
289 \&    parameter format => (
290 \&        isa     => (enum [\*(AqStorable\*(Aq, \*(AqYAML\*(Aq, \*(AqJSON\*(Aq]),
291 \&        default => \*(AqStorable\*(Aq,
292 \&    );
293 \&
294 \&    role {
295 \&        my $p = shift;
296 \&        if ($p\->format eq \*(AqStorable\*(Aq) {
297 \&            method freeze => \e&Storable::freeze;
298 \&            method thaw   => \e&Storable::thaw;
299 \&        }
300 \&        elsif ($p\->format eq \*(AqYAML\*(Aq) {
301 \&            method freeze => \e&YAML::Dump;
302 \&            method thaw   => \e&YAML::Load;
303 \&        }
304 \&        ...
305 \&    }
306 .Ve
307 .IP "Additional validation" 4
308 .IX Item "Additional validation"
309 Ordinary roles can require that its consumers have a particular list of method
310 names. Since parameterized roles have direct access to its consumer, you can inspect it and throw errors if the consumer does not meet your needs.
311 .Sp
312 .Vb 4
313 \&    role {
314 \&        my $p    = shift;
315 \&        my %args = @_;
316 \&        my $consumer = $args{consumer};
317 \&
318 \&        $consumer\->find_attribute_by_name(\*(Aqstack\*(Aq)
319 \&            or confess "You must have a \*(Aqstack\*(Aq attribute";
320 \&
321 \&        my $push = $consumer\->find_method_by_name(\*(Aqpush\*(Aq)
322 \&            or confess "You must have a \*(Aqpush\*(Aq method";
323 \&
324 \&        my $params = $push\->parsed_signature\->positional_params\->params;
325 \&        @$params == 1
326 \&            or confess "Your push method must take a single parameter";
327 \&
328 \&        $params\->[0]\->sigil eq \*(Aq$\*(Aq
329 \&            or confess "Your push parameter must be a scalar";
330 \&
331 \&        ...
332 \&    }
333 .Ve