Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / Moose::Cookbook::Meta::Recipe3.3pm
1 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sh \" Subsection heading
6 .br
7 .if t .Sp
8 .ne 5
9 .PP
10 \fB\\$1\fR
11 .PP
12 ..
13 .de Sp \" Vertical space (when we can't use .PP)
14 .if t .sp .5v
15 .if n .sp
16 ..
17 .de Vb \" Begin verbatim text
18 .ft CW
19 .nf
20 .ne \\$1
21 ..
22 .de Ve \" End verbatim text
23 .ft R
24 .fi
25 ..
26 .\" Set up some character translations and predefined strings.  \*(-- will
27 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28 .\" double quote, and \*(R" will give a right double quote.  | will give a
29 .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
30 .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
31 .\" expand to `' in nroff, nothing in troff, for use with C<>.
32 .tr \(*W-|\(bv\*(Tr
33 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
34 .ie n \{\
35 .    ds -- \(*W-
36 .    ds PI pi
37 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
39 .    ds L" ""
40 .    ds R" ""
41 .    ds C` ""
42 .    ds C' ""
43 'br\}
44 .el\{\
45 .    ds -- \|\(em\|
46 .    ds PI \(*p
47 .    ds L" ``
48 .    ds R" ''
49 'br\}
50 .\"
51 .\" If the F register is turned on, we'll generate index entries on stderr for
52 .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53 .\" entries marked with X<> in POD.  Of course, you'll have to process the
54 .\" output yourself in some meaningful fashion.
55 .if \nF \{\
56 .    de IX
57 .    tm Index:\\$1\t\\n%\t"\\$2"
58 ..
59 .    nr % 0
60 .    rr F
61 .\}
62 .\"
63 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
64 .\" way too many mistakes in technical documents.
65 .hy 0
66 .if n .na
67 .\"
68 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
70 .    \" fudge factors for nroff and troff
71 .if n \{\
72 .    ds #H 0
73 .    ds #V .8m
74 .    ds #F .3m
75 .    ds #[ \f1
76 .    ds #] \fP
77 .\}
78 .if t \{\
79 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
80 .    ds #V .6m
81 .    ds #F 0
82 .    ds #[ \&
83 .    ds #] \&
84 .\}
85 .    \" simple accents for nroff and troff
86 .if n \{\
87 .    ds ' \&
88 .    ds ` \&
89 .    ds ^ \&
90 .    ds , \&
91 .    ds ~ ~
92 .    ds /
93 .\}
94 .if t \{\
95 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
101 .\}
102 .    \" troff and (daisy-wheel) nroff accents
103 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110 .ds ae a\h'-(\w'a'u*4/10)'e
111 .ds Ae A\h'-(\w'A'u*4/10)'E
112 .    \" corrections for vroff
113 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115 .    \" for low resolution devices (crt and lpr)
116 .if \n(.H>23 .if \n(.V>19 \
117 \{\
118 .    ds : e
119 .    ds 8 ss
120 .    ds o a
121 .    ds d- d\h'-1'\(ga
122 .    ds D- D\h'-1'\(hy
123 .    ds th \o'bp'
124 .    ds Th \o'LP'
125 .    ds ae ae
126 .    ds Ae AE
127 .\}
128 .rm #[ #] #H #V #F C
129 .\" ========================================================================
130 .\"
131 .IX Title "Moose::Cookbook::Meta::Recipe3 3"
132 .TH Moose::Cookbook::Meta::Recipe3 3 "2009-10-24" "perl v5.8.7" "User Contributed Perl Documentation"
133 .SH "NAME"
134 Moose::Cookbook::Meta::Recipe3 \- Labels implemented via attribute traits
135 .SH "SYNOPSIS"
136 .IX Header "SYNOPSIS"
137 .Vb 2
138 \&  package MyApp::Meta::Attribute::Trait::Labeled;
139 \&  use Moose::Role;
140 .Ve
141 .PP
142 .Vb 5
143 \&  has label => (
144 \&      is        => 'rw',
145 \&      isa       => 'Str',
146 \&      predicate => 'has_label',
147 \&  );
148 .Ve
149 .PP
150 .Vb 2
151 \&  package Moose::Meta::Attribute::Custom::Trait::Labeled;
152 \&  sub register_implementation {'MyApp::Meta::Attribute::Trait::Labeled'}
153 .Ve
154 .PP
155 .Vb 2
156 \&  package MyApp::Website;
157 \&  use Moose;
158 .Ve
159 .PP
160 .Vb 6
161 \&  has url => (
162 \&      traits => [qw/Labeled/],
163 \&      is     => 'rw',
164 \&      isa    => 'Str',
165 \&      label  => "The site's URL",
166 \&  );
167 .Ve
168 .PP
169 .Vb 4
170 \&  has name => (
171 \&      is  => 'rw',
172 \&      isa => 'Str',
173 \&  );
174 .Ve
175 .PP
176 .Vb 2
177 \&  sub dump {
178 \&      my $self = shift;
179 .Ve
180 .PP
181 .Vb 1
182 \&      my $meta = $self\->meta;
183 .Ve
184 .PP
185 .Vb 1
186 \&      my $dump = '';
187 .Ve
188 .PP
189 .Vb 2
190 \&      for my $attribute ( map { $meta\->get_attribute($_) }
191 \&          sort $meta\->get_attribute_list ) {
192 .Ve
193 .PP
194 .Vb 7
195 \&          if (   $attribute\->does('MyApp::Meta::Attribute::Trait::Labeled')
196 \&              && $attribute\->has_label ) {
197 \&              $dump .= $attribute\->label;
198 \&          }
199 \&          else {
200 \&              $dump .= $attribute\->name;
201 \&          }
202 .Ve
203 .PP
204 .Vb 3
205 \&          my $reader = $attribute\->get_read_method;
206 \&          $dump .= ": " . $self\->$reader . "\en";
207 \&      }
208 .Ve
209 .PP
210 .Vb 2
211 \&      return $dump;
212 \&  }
213 .Ve
214 .PP
215 .Vb 1
216 \&  package main;
217 .Ve
218 .PP
219 .Vb 1
220 \&  my $app = MyApp::Website\->new( url => "http://google.com", name => "Google" );
221 .Ve
222 .SH "BUT FIRST"
223 .IX Header "BUT FIRST"
224 This recipe is a variation on
225 Moose::Cookbook::Meta::Recipe2. Please read that recipe first.
226 .SH "MOTIVATION"
227 .IX Header "MOTIVATION"
228 In Moose::Cookbook::Meta::Recipe2, we created an attribute
229 metaclass which lets you provide a label for attributes.
230 .PP
231 Using a metaclass works fine until you realize you want to add a label
232 \&\fIand\fR an expiration, or some other combination of new behaviors. You
233 could create yet another metaclass which subclasses those two, but
234 that makes a mess, especially if you want to mix and match behaviors
235 across many attributes.
236 .PP
237 Fortunately, Moose provides a much saner alternative, which is to
238 encapsulate each extension as a role, not a class. We can make a role
239 which adds a label to an attribute, and could make another to
240 implement expiration.
241 .SH "TRAITS"
242 .IX Header "TRAITS"
243 Roles that apply to metaclasses have a special name: traits. Don't let
244 the change in nomenclature fool you, \fBtraits are just roles\fR.
245 .PP
246 \&\*(L"has\*(R" in Moose allows you to pass a \f(CW\*(C`traits\*(C'\fR parameter for an
247 attribute. This parameter takes a list of trait names which are
248 composed into an anonymous metaclass, and that anonymous metaclass is
249 used for the attribute.
250 .PP
251 Yes, we still have lots of metaclasses in the background, but they're
252 managed by Moose for you.
253 .PP
254 Traits can do anything roles can do. They can add or refine
255 attributes, wrap methods, provide more methods, define an interface,
256 etc. The only difference is that you're now changing the attribute
257 metaclass instead of a user-level class.
258 .SH "DISSECTION"
259 .IX Header "DISSECTION"
260 A side-by-side look of the code examples in this recipe and recipe 2
261 show that defining and using a trait is very similar to a full-blown
262 metaclass.
263 .PP
264 .Vb 2
265 \&  package MyApp::Meta::Attribute::Trait::Labeled;
266 \&  use Moose::Role;
267 .Ve
268 .PP
269 .Vb 5
270 \&  has label => (
271 \&      is        => 'rw',
272 \&      isa       => 'Str',
273 \&      predicate => 'has_label',
274 \&  );
275 .Ve
276 .PP
277 Instead of subclassing Moose::Meta::Attribute, we define a role. As
278 with our metaclass in recipe 2,
279 registering our role allows us to refer to it by a short name.
280 .PP
281 .Vb 2
282 \&  package Moose::Meta::Attribute::Custom::Trait::Labeled;
283 \&  sub register_implementation { 'MyApp::Meta::Attribute::Trait::Labeled' }
284 .Ve
285 .PP
286 Moose looks for the \f(CW\*(C`register_implementation\*(C'\fR method in
287 \&\f(CW\*(C`Moose::Meta::Attribute::Custom::Trait::$TRAIT_NAME\*(C'\fR to find the full
288 name of the trait.
289 .PP
290 For the rest of the code, we will only cover what is \fIdifferent\fR from
291 recipe 2.
292 .PP
293 .Vb 6
294 \&  has url => (
295 \&      traits => [qw/Labeled/],
296 \&      is     => 'rw',
297 \&      isa    => 'Str',
298 \&      label  => "The site's URL",
299 \&  );
300 .Ve
301 .PP
302 Instead of passing a \f(CW\*(C`metaclass\*(C'\fR parameter, this time we pass
303 \&\f(CW\*(C`traits\*(C'\fR. This contains a list of trait names. Moose will build an
304 anonymous attribute metaclass from these traits and use it for this
305 attribute. Passing a \f(CW\*(C`label\*(C'\fR parameter works just as it did with the
306 metaclass example.
307 .PP
308 .Vb 4
309 \&          if (   $attribute\->does('MyApp::Meta::Attribute::Trait::Labeled')
310 \&              && $attribute\->has_label ) {
311 \&              $dump .= $attribute\->label;
312 \&          }
313 .Ve
314 .PP
315 In the metaclass example, we used \f(CW\*(C`$attribute\->isa\*(C'\fR. With a role,
316 we instead ask if the meta-attribute object \f(CW\*(C`does\*(C'\fR the required
317 role. If it does not do this role, the attribute meta object won't
318 have the \f(CW\*(C`has_label\*(C'\fR method.
319 .PP
320 That's all. Everything else is the same!
321 .SH "TURNING A METACLASS INTO A TRAIT"
322 .IX Header "TURNING A METACLASS INTO A TRAIT"
323 \&\*(L"But wait!\*(R" you protest. \*(L"I've already written all of my extensions as
324 attribute metaclasses. I don't want to break all that code out there.\*(R"
325 .PP
326 Fortunately, you can easily turn a metaclass into a trait and still
327 provide the original metaclass:
328 .PP
329 .Vb 4
330 \&  package MyApp::Meta::Attribute::Labeled;
331 \&  use Moose;
332 \&  extends 'Moose::Meta::Attribute';
333 \&  with 'MyApp::Meta::Attribute::Trait::Labeled';
334 .Ve
335 .PP
336 .Vb 2
337 \&  package Moose::Meta::Attribute::Custom::Labeled;
338 \&  sub register_implementation { 'MyApp::Meta::Attribute::Labeled' }
339 .Ve
340 .PP
341 Unfortunately, going the other way (providing a trait created from a
342 metaclass) is more tricky.
343 .SH "CONCLUSION"
344 .IX Header "CONCLUSION"
345 If you're extending your attributes, it's easier and more flexible to
346 provide composable bits of behavior than to subclass
347 Moose::Meta::Attribute. Using traits lets you cooperate with other
348 extensions, either from \s-1CPAN\s0 or that you might write in the
349 future. Moose makes it easy to create attribute metaclasses on the fly
350 by providing a list of trait names to \*(L"has\*(R" in Moose.
351 .SH "AUTHOR"
352 .IX Header "AUTHOR"
353 Shawn M Moore <sartak@gmail.com>
354 .PP
355 Dave Rolsky <autarch@urth.org<gt>
356 .SH "COPYRIGHT AND LICENSE"
357 .IX Header "COPYRIGHT AND LICENSE"
358 Copyright 2006\-2009 by Infinity Interactive, Inc.
359 .PP
360 <http://www.iinteractive.com>
361 .PP
362 This library is free software; you can redistribute it and/or modify
363 it under the same terms as Perl itself.