renames
[gitmo/Moose.git] / lib / Moose / Cookbook / Recipe1.pod
1
2 =pod
3
4 =head1 NAME
5
6 Moose::Cookbook::Recipe1 - The (always classic) B<Point> example.
7
8 =head1 SYNOPSIS
9
10   package Point;
11   use strict;
12   use warnings; 
13   use Moose;
14         
15   has 'x' => (isa => 'Int', is => 'ro');
16   has 'y' => (isa => 'Int', is => 'rw');
17   
18   sub clear {
19       my $self = shift;
20       $self->{x} = 0;
21       $self->y(0);    
22   }
23   
24   package Point3D;
25   use strict;
26   use warnings;
27   use Moose;
28   
29   extends 'Point';
30   
31   has 'z' => (isa => 'Int');
32   
33   after 'clear' => sub {
34       my $self = shift;
35       $self->{z} = 0;
36   };
37
38 =head1 DESCRIPTION
39
40 This is the classic Point example. This one in particular I took 
41 from the Perl 6 Apocalypse 12 document, but it is similar to the 
42 example found in the classic K&R C book as well, and many other 
43 places. And now, onto the code:
44
45 As with all Perl 5 classes, a Moose class is defined in a package. 
46 Of course we always use C<strict> and C<warnings> (don't forget 
47 that a kitten will die if you don't) and then we C<use Moose>.
48
49 By loading Moose, we are enabeling the Moose "environment" to be 
50 loaded within our package. This means that we export some functions 
51 which serve as Moose "keywords". This is nothing fancier than that, 
52 just plain old exported functions.
53
54 Another important thing happens at this stage as well. Moose will 
55 automatically set your package's superclass to be L<Moose::Object>.
56 The reason we do this, is so that we can be sure that you will 
57 inherit from L<Moose::Object> and get the benefits that provides 
58 (see the L<Moose::Object> for those details). However, you don't 
59 actually I<have> to inherit from L<Moose::Object> if you don't  
60 want to, all other features of Moose are still accessible to you.
61
62 Now, onto the keywords. The first one we see here is C<has>, which 
63 defines an instance attribute in your class. 
64
65   has 'x' => (isa => 'Int', is => 'ro');
66
67 This will create an attribute named C<x>, it will expect that the 
68 value stored in the attribute to pass the type constraint C<Int> (1), 
69 and the accessor generated for this attribute will be read-only 
70 (abbreviated as C<ro>).
71
72 The next C<has> line is very similar, with only one difference.
73
74   has 'y' => (isa => 'Int', is => 'rw');
75
76 For the C<y> attribute a read/write accessor will be generated 
77 (abbreviated as C<rw>). 
78
79 At this point the attributes have been defined, and it is time to 
80 define our methods. In Moose, as with regular Perl 5 OO, a method 
81 is just a subroutine defined within the package. So here we create 
82 the C<clear> method.
83
84   sub clear {
85       my $self = shift;
86       $self->{x} = 0;
87       $self->y(0);    
88   }
89
90 It is pretty standard, the only thing to note is that we are directly 
91 accessing the C<x> slot in the instance L<(2)>. This is because the 
92 value was created with a read-only accessor. This also shows that Moose 
93 objects are not anything out of the ordinary, but just regular old 
94 blessed HASH references. This means they are very compatible with 
95 other Perl 5 (non-Moose) classes as well. 
96
97 The next part of the code to review is the B<Point> subclass, 
98 B<Point3D>. The first item you might notice is that we do not use 
99 the standard C<use base> declaration here. Instead we use the Moose 
100 keyword C<extends> like so:
101
102   extends 'Point';
103
104 This keyword will function very much like C<use base> does in that 
105 it will make an attempt to load your class if it has not already been 
106 loaded. However, it differs on one important point. The C<extends> 
107 keyword will overwrite any previous values in your package's C<@ISA>, 
108 where C<use base> will C<push> values onto the package's C<@ISA>. It 
109 is my opinion that the behavior of C<extends> is more intuitive in 
110 that it is more explicit about defining the superclass relationship.
111
112 A small digression here, both Moose and C<extends> support multiple 
113 inheritence. You simply pass all the superclasses to C<extends>, 
114 like so:
115
116   extends 'Foo', 'Bar', 'Baz';
117   
118 Now, back to our B<Point3D> class. The next thing we do is to create 
119 a new attribute for B<Point3D> called C<z>.
120
121   has 'z' => (isa => 'Int');
122
123 As with B<Point>'s C<x> and C<y> attributes, this attribute has a 
124 type constraint of C<Int>, but it differs in that it does B<not> 
125 ask for any autogenerated accessors. The result being (aside from 
126 breaking object encapsulation), that C<x> is a private attribute.
127
128 Next comes another Moose feature which we call method "modifiers" 
129 (or method "advice" for the AOP inclined). The modifier used here 
130 is the C<after> modifier, and looks like this:
131
132   after 'clear' => sub {
133       my $self = shift;
134       $self->{z} = 0;
135   };
136
137 This modifier tells Moose to install a C<clear> method for 
138 B<Point3D> that will first run the C<clear> method for the 
139 superclass (in this case C<Point::clear>), and then run this 
140 method I<after> it (passing in the same arguments as the original 
141 method). 
142
143 Now, of course using the C<after> modifier is not the only way to 
144 accomplish this. I mean, after all, this B<is> Perl right? You 
145 would get the same results with this code:
146
147   sub clear {
148       my $self = shift;
149       $self->SUPER::clear();
150       $self->{z} = 0;
151   }
152
153 You could also use another Moose method modifier, C<override> here, 
154 and get the same results again. Here is how that would look.
155
156   override 'clear' => sub {
157       my $self = shift;
158       super();
159       $self->{z} = 0;
160   };
161   
162 The C<override> modifier allows you to use the C<super> keyword 
163 within it to dispatch to the superclass's method in a very Ruby-ish 
164 style.
165
166 Now of course, what use is a class if you cant instantiate objects 
167 with it. Now since B<Point> inherits from L<Moose::Object>, it will 
168 inherit the default L<Moose::Object> constructor called C<new>. Here 
169 are two examples of how that is used:
170
171   my $point = Point->new(x => 1, y => 2);   
172   my $point3d = Point3D->new(x => 1, y => 2, z => 3);
173
174 As you can see, C<new> accepts named argument pairs for any of the 
175 attributes. It does not I<require> that you pass in the all the 
176 attributes, and it will politely ignore any named arguments it does 
177 not recognize. 
178
179 From here on, you can use C<$point> and C<$point3d> just as you would 
180 any other Perl 5 object. For a more detailed example of what can be 
181 done, you can refer to the F<t/001_basic.t> test file.
182
183 =head1 CONCLUSION
184
185 I hope this recipe has given you some explaination of how to use 
186 Moose to build you Perl 5 classes. The next recipe will build upon 
187 the basics shown here with more complex attributes and methods. 
188 Please read on :)
189
190 =head1 FOOTNOTES
191
192 =over 4
193
194 =item (1)
195
196 Several default type constraints are provided by Moose, of which 
197 C<Int> is one. For more information on the built-in type constraints 
198 and the type constraint system in general, see the 
199 L<Moose::Util::TypeConstraints> documentation.
200
201 =item (2)
202
203 Future plans for Moose include allowing for alternate instance 
204 structures such as blessed ARRAY refs and such. If you want you Moose 
205 classes to be interchangable, it is advised that you avoid direct 
206 instance access, like that which is shown above.
207
208 =back
209
210 =head1 SEE ALSO
211
212 =over 4
213
214 =item Method Modifiers
215
216 The concept of method modifiers is directly ripped off from CLOS. A 
217 great explaination of them can be found by following this link.
218
219 L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>
220
221 =back
222
223 =head1 AUTHOR
224
225 Stevan Little E<lt>stevan@iinteractive.comE<gt>
226
227 =head1 COPYRIGHT AND LICENSE
228
229 Copyright 2006 by Infinity Interactive, Inc.
230
231 L<http://www.iinteractive.com>
232
233 This library is free software; you can redistribute it and/or modify
234 it under the same terms as Perl itself.
235
236 =cut