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