Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / Moose::Cookbook::Basics::Recipe9.3pm
CommitLineData
3fea05b9 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::Basics::Recipe9 3"
132.TH Moose::Cookbook::Basics::Recipe9 3 "2009-07-03" "perl v5.8.7" "User Contributed Perl Documentation"
133.SH "NAME"
134Moose::Cookbook::Basics::Recipe9 \- Operator overloading, subtypes, and coercion
135.SH "SYNOPSIS"
136.IX Header "SYNOPSIS"
137.Vb 1
138\& package Human;
139.Ve
140.PP
141.Vb 2
142\& use Moose;
143\& use Moose::Util::TypeConstraints;
144.Ve
145.PP
146.Vb 3
147\& subtype 'Gender'
148\& => as 'Str'
149\& => where { $_ =~ m{^[mf]$}s };
150.Ve
151.PP
152.Vb 1
153\& has 'gender' => ( is => 'ro', isa => 'Gender', required => 1 );
154.Ve
155.PP
156.Vb 2
157\& has 'mother' => ( is => 'ro', isa => 'Human' );
158\& has 'father' => ( is => 'ro', isa => 'Human' );
159.Ve
160.PP
161.Vb 1
162\& use overload '+' => \e&_overload_add, fallback => 1;
163.Ve
164.PP
165.Vb 2
166\& sub _overload_add {
167\& my ( $one, $two ) = @_;
168.Ve
169.PP
170.Vb 2
171\& die('Only male and female humans may create children')
172\& if ( $one\->gender() eq $two\->gender() );
173.Ve
174.PP
175.Vb 2
176\& my ( $mother, $father )
177\& = ( $one\->gender eq 'f' ? ( $one, $two ) : ( $two, $one ) );
178.Ve
179.PP
180.Vb 2
181\& my $gender = 'f';
182\& $gender = 'm' if ( rand() >= 0.5 );
183.Ve
184.PP
185.Vb 6
186\& return Human\->new(
187\& gender => $gender,
188\& mother => $mother,
189\& father => $father,
190\& );
191\& }
192.Ve
193.SH "DESCRIPTION"
194.IX Header "DESCRIPTION"
195This Moose cookbook recipe shows how operator overloading, coercion,
196and sub types can be used to mimic the human reproductive system
197(well, the selection of genes at least).
198.SH "INTRODUCTION"
199.IX Header "INTRODUCTION"
200Our \f(CW\*(C`Human\*(C'\fR class uses operator overloading to allow us to \*(L"add\*(R" two
201humans together and produce a child. Our implementation does require
202that the two objects be of opposite genders. Remember, we're talking
203about biological reproduction, not marriage.
204.PP
205While this example works as\-is, we can take it a lot further by adding
206genes into the mix. We'll add the two genes that control eye color,
207and use overloading to combine the genes from the parent to model the
208biology.
209.Sh "What is Operator Overloading?"
210.IX Subsection "What is Operator Overloading?"
211Overloading is \fInot\fR a Moose-specific feature. It's a general \s-1OO\s0
212concept that is implemented in Perl with the \f(CW\*(C`overload\*(C'\fR
213pragma. Overloading lets objects do something sane when used with
214Perl's built in operators, like addition (\f(CW\*(C`+\*(C'\fR) or when used as a
215string.
216.PP
217In this example we overload addition so we can write code like
218\&\f(CW\*(C`$child = $mother + $father\*(C'\fR.
219.SH "GENES"
220.IX Header "GENES"
221There are many genes which affect eye color, but there are two which
222are most important, \fIgey\fR and \fIbey2\fR. We will start by making a
223class for each gene.
224.Sh "Human::Gene::bey2"
225.IX Subsection "Human::Gene::bey2"
226.Vb 1
227\& package Human::Gene::bey2;
228.Ve
229.PP
230.Vb 2
231\& use Moose;
232\& use Moose::Util::TypeConstraints;
233.Ve
234.PP
235.Vb 1
236\& type 'bey2_color' => where { $_ =~ m{^(?:brown|blue)$} };
237.Ve
238.PP
239.Vb 1
240\& has 'color' => ( is => 'ro', isa => 'bey2_color' );
241.Ve
242.PP
243This class is trivial, We have a type constraint for the allowed
244colors, and a \f(CW\*(C`color\*(C'\fR attribute.
245.Sh "Human::Gene::gey"
246.IX Subsection "Human::Gene::gey"
247.Vb 1
248\& package Human::Gene::gey;
249.Ve
250.PP
251.Vb 2
252\& use Moose;
253\& use Moose::Util::TypeConstraints;
254.Ve
255.PP
256.Vb 1
257\& type 'gey_color' => where { $_ =~ m{^(?:green|blue)$} };
258.Ve
259.PP
260.Vb 1
261\& has 'color' => ( is => 'ro', isa => 'gey_color' );
262.Ve
263.PP
264This is nearly identical to the \f(CW\*(C`Humane::Gene::bey2\*(C'\fR class, except
265that the \fIgey\fR gene allows for different colors.
266.SH "EYE COLOR"
267.IX Header "EYE COLOR"
268We could just give add four attributes (two of each gene) to the
269\&\f(CW\*(C`Human\*(C'\fR class, but this is a bit messy. Instead, we'll abstract the
270genes into a container class, \f(CW\*(C`Human::EyeColor\*(C'\fR. Then a \f(CW\*(C`Human\*(C'\fR can
271have a single \f(CW\*(C`eye_color\*(C'\fR attribute.
272.PP
273.Vb 1
274\& package Human::EyeColor;
275.Ve
276.PP
277.Vb 2
278\& use Moose;
279\& use Moose::Util::TypeConstraints;
280.Ve
281.PP
282.Vb 3
283\& coerce 'Human::Gene::bey2'
284\& => from 'Str'
285\& => via { Human::Gene::bey2\->new( color => $_ ) };
286.Ve
287.PP
288.Vb 3
289\& coerce 'Human::Gene::gey'
290\& => from 'Str'
291\& => via { Human::Gene::gey\->new( color => $_ ) };
292.Ve
293.PP
294.Vb 2
295\& has [qw( bey2_1 bey2_2 )] =>
296\& ( is => 'ro', isa => 'Human::Gene::bey2', coerce => 1 );
297.Ve
298.PP
299.Vb 2
300\& has [qw( gey_1 gey_2 )] =>
301\& ( is => 'ro', isa => 'Human::Gene::gey', coerce => 1 );
302.Ve
303.PP
304The eye color class has two of each type of gene. We've also created a
305coercion for each class that coerces a string into a new object. Note
306that a coercion will fail if it attempts to coerce a string like
307\&\*(L"indigo\*(R", because that is not a valid color for either type of gene.
308.PP
309As an aside, you can see that we can define several identical
310attributes at once by supply an array reference of names as the first
311argument to \f(CW\*(C`has\*(C'\fR.
312.PP
313We also need a method to calculate the actual eye color that results
314from a set of genes. The \fIbey2\fR brown gene is dominant over both blue
315and green. The \fIgey\fR green gene dominant over blue.
316.PP
317.Vb 2
318\& sub color {
319\& my ($self) = @_;
320.Ve
321.PP
322.Vb 3
323\& return 'brown'
324\& if ( $self\->bey2_1\->color() eq 'brown'
325\& or $self\->bey2_2\->color() eq 'brown' );
326.Ve
327.PP
328.Vb 3
329\& return 'green'
330\& if ( $self\->gey_1\->color() eq 'green'
331\& or $self\->gey_2\->color() eq 'green' );
332.Ve
333.PP
334.Vb 2
335\& return 'blue';
336\& }
337.Ve
338.PP
339We'd like to be able to treat a \f(CW\*(C`Human::EyeColor\*(C'\fR object as a string,
340so we define a string overloading for the class:
341.PP
342.Vb 1
343\& use overload '""' => \e&color, fallback => 1;
344.Ve
345.PP
346Finally, we need to define overloading for addition. That way we can
347add together to \f(CW\*(C`Human::EyeColor\*(C'\fR objects and get a new one with a
348new (genetically correct) eye color.
349.PP
350.Vb 1
351\& use overload '+' => \e&_overload_add, fallback => 1;
352.Ve
353.PP
354.Vb 2
355\& sub _overload_add {
356\& my ( $one, $two ) = @_;
357.Ve
358.PP
359.Vb 2
360\& my $one_bey2 = 'bey2_' . _rand2();
361\& my $two_bey2 = 'bey2_' . _rand2();
362.Ve
363.PP
364.Vb 2
365\& my $one_gey = 'gey_' . _rand2();
366\& my $two_gey = 'gey_' . _rand2();
367.Ve
368.PP
369.Vb 7
370\& return Human::EyeColor\->new(
371\& bey2_1 => $one\->$one_bey2\->color(),
372\& bey2_2 => $two\->$two_bey2\->color(),
373\& gey_1 => $one\->$one_gey\->color(),
374\& gey_2 => $two\->$two_gey\->color(),
375\& );
376\& }
377.Ve
378.PP
379.Vb 3
380\& sub _rand2 {
381\& return 1 + int( rand(2) );
382\& }
383.Ve
384.PP
385When two eye color objects are added together the \f(CW\*(C`_overload_add()\*(C'\fR
386method will be passed two \f(CW\*(C`Human::EyeColor\*(C'\fR objects. These are the
387left and right side operands for the \f(CW\*(C`+\*(C'\fR operator. This method
388returns a new \f(CW\*(C`Human::EyeColor\*(C'\fR object.
389.ie n .SH "ADDING EYE COLOR TO ""Human""s"
390.el .SH "ADDING EYE COLOR TO \f(CWHuman\fPs"
391.IX Header "ADDING EYE COLOR TO Humans"
392Our original \f(CW\*(C`Human\*(C'\fR class requires just a few changes to incorporate
393our new \f(CW\*(C`Human::EyeColor\*(C'\fR class.
394.PP
395.Vb 1
396\& use List::MoreUtils qw( zip );
397.Ve
398.PP
399.Vb 4
400\& coerce 'Human::EyeColor'
401\& => from 'ArrayRef'
402\& => via { my @genes = qw( bey2_1 bey2_2 gey_1 gey_2 );
403\& return Human::EyeColor\->new( zip( @genes, @{$_} ) ); };
404.Ve
405.PP
406.Vb 6
407\& has 'eye_color' => (
408\& is => 'ro',
409\& isa => 'Human::EyeColor',
410\& coerce => 1,
411\& required => 1,
412\& );
413.Ve
414.PP
415We also need to modify \f(CW\*(C`_overload_add()\*(C'\fR in the \f(CW\*(C`Human\*(C'\fR class to
416account for eye color:
417.PP
418.Vb 6
419\& return Human\->new(
420\& gender => $gender,
421\& eye_color => ( $one\->eye_color() + $two\->eye_color() ),
422\& mother => $mother,
423\& father => $father,
424\& );
425.Ve
426.SH "CONCLUSION"
427.IX Header "CONCLUSION"
428The three techniques we used, overloading, subtypes, and coercion,
429combine to provide a powerful interface.
430.PP
431If you'd like to learn more about overloading, please read the
432documentation for the overload pragma.
433.PP
434To see all the code we created together, take a look at
435\&\fIt/000_recipes/basics/010_genes.t\fR.
436.SH "NEXT STEPS"
437.IX Header "NEXT STEPS"
438Has this been a real project we'd probably want to:
439.IP "Better Randomization with Crypt::Random" 4
440.IX Item "Better Randomization with Crypt::Random"
441.PD 0
442.IP "Characteristic Base Class" 4
443.IX Item "Characteristic Base Class"
444.IP "Mutating Genes" 4
445.IX Item "Mutating Genes"
446.IP "More Characteristics" 4
447.IX Item "More Characteristics"
448.IP "Artificial Life" 4
449.IX Item "Artificial Life"
450.PD
451.SH "AUTHORS"
452.IX Header "AUTHORS"
453Aran Clary Deltac <bluefeet@cpan.org>
454.PP
455Dave Rolsky <autarch@urth.org>
456.SH "LICENSE"
457.IX Header "LICENSE"
458This work is licensed under a Creative Commons Attribution 3.0 Unported License.
459.PP
460License details are at: <http://creativecommons.org/licenses/by/3.0/>