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