Revised Basics Recipe 1 a fair bit ...
[gitmo/Moose.git] / lib / Moose / Cookbook / Basics / Recipe1.pod
1
2 =pod
3
4 =head1 NAME
5
6 Moose::Cookbook::Basics::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 => 'rw', required => 1);
14   has 'y' => (isa => 'Int', is => 'rw', required => 1);
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', is => 'rw', required => 1);
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. It is taken directly from the Perl
37 6 Apocalypse 12 document, and is similar to the example found in the
38 classic K&R C book as well.
39
40 As with all Perl 5 classes, a Moose class is defined in a package.
41 Moose handles turning on C<strict> and C<warnings> for us, so all we
42 need to do is say C<use Moose>, and no kittens will die.
43
44 When Moose is loaded, it exports a set of sugar functions into our
45 package. This means that we import some functions which serve as Moose
46 "keywords". These aren't real language keywords, they're just Perl
47 functions exported into our package.
48
49 Moose automatically makes our package a subclass of L<Moose::Object>.
50 The L<Moose::Object> class provides us with a constructor that
51 respects our attributes, as well other features. See L<Moose::Object>
52 for details.
53
54 Now, onto the keywords. The first one we see here is C<has>, which
55 defines an instance attribute in our class:
56
57   has 'x' => (isa => 'Int', is => 'rw', required => 1);
58
59 This will create an attribute named C<x>. The C<isa> parameter says
60 that we expect the value stored in this attribute to pass the type
61 constraint for C<Int> (1). The accessor generated for this attribute
62 will be read-write.
63
64 The C<< requires => 1 >> parameter means that this attribute must be
65 provided when a new object is created. A point object without
66 coordinates doesn't make much sense, so we don't allow it.
67
68 We have defined our attributes; next we define our methods. In Moose,
69 as with regular Perl 5 OO, a method is just a subroutine defined
70 within the package:
71
72   sub clear {
73       my $self = shift;
74       $self->x(0);
75       $self->y(0);
76   }
77
78 That concludes the B<Point> class.
79
80 Next we have a subclass of B<Point>, B<Point3D>. To declare our
81 superclass, we use the Moose keyword C<extends>:
82
83   extends 'Point';
84
85 The C<extends> keyword works much like C<use base>. First, it will
86 attempt to load your class if needed. However, unlike C<base>, the
87 C<extends> keyword will I<overwrite> any previous values in your
88 package's C<@ISA>, where C<use base> will C<push> values onto the
89 package's C<@ISA>.
90
91 It is my opinion that the behavior of C<extends> is more intuitive.
92 (2).
93
94 Next we create a new attribute for B<Point3D> called C<z>.
95
96   has 'z' => (isa => 'Int', is => 'rw', required => 1);
97
98 This attribute is just like B<Point>'s C<x> and C<y> attributes.
99
100 The C<after> keyword demonstrates a Moose feature called "method
101 modifiers" (or "advice" for the AOP inclined):
102
103   after 'clear' => sub {
104       my $self = shift;
105       $self->z(0);
106   };
107
108 When C<clear> is called on a B<Point3D> object, our modifier method
109 gets called as well. Unsurprisingly, the modifier is called I<after>
110 the real method.
111
112 In this case, the real C<clear> method is inherited from B<Point>. Our
113 modifier method receives the same arguments as those passed to the
114 modified method (just C<$self> here).
115
116 Of course, using the C<after> modifier is not the only way to
117 accomplish this. This B<is> Perl, right? You can get the same results
118 with this code:
119
120   sub clear {
121       my $self = shift;
122       $self->SUPER::clear();
123       $self->z(0);
124   }
125
126 You could also use another Moose method modifier, C<override>:
127
128   override 'clear' => sub {
129       my $self = shift;
130       super();
131       $self->z(0);
132   };
133
134 The C<override> modifier allows you to use the C<super> keyword to
135 dispatch to the superclass's method in a very Ruby-ish style.
136
137 The choice of whether to use a method modifier, and which one to use,
138 is often a question of style as much as functionality.
139
140 Since B<Point> inherits from L<Moose::Object>, it will also inherit
141 the default L<Moose::Object> constructor:
142
143   my $point   = Point  ->new(x => 1, y => 2);
144   my $point3d = Point3D->new(x => 1, y => 2, z => 3);
145
146 The C<new> constructor accepts a named argument pair for each
147 attribute defined by the class. In this particular example, the
148 attributes are required, and calling C<new> without them will throw an
149 error.
150
151 From here on, we can use C<$point> and C<$point3d> just as you would
152 any other Perl 5 object. For a more detailed example of what can be
153 done, you can refer to the F<t/000_recipes/basic/001_point.t> test
154 file.
155
156 =head2 Moose Objects are Just Hashrefs
157
158 While this all may appear rather magical, it's important to realize
159 that Moose objects are just hash references under the hood (3). For
160 example, you could pass C<$self> to C<Data::Dumper> and you'd get
161 exactly what you'd expect.
162
163 You could even poke around inside the object's data structure, but
164 that is strongly discouraged.
165
166 The fact that Moose objects are hashrefs means it is easy to use Moose
167 to extend non-Moose classes, as long as they too are hash
168 references. If you want to extend a non-hashref class, check out
169 C<MooseX::InsideOut>.
170
171 =head1 CONCLUSION
172
173 This recipe demonstrates some basic Moose concepts. The next recipe
174 will build upon the basics shown here with more complex attributes and
175 methods. Please read on :)
176
177 =head1 FOOTNOTES
178
179 =over 4
180
181 =item (1)
182
183 Moose provides a number of builtin type constraints are provided by,
184 of which C<Int> is one. For more information on the type constraint
185 system, see L<Moose::Util::TypeConstraints>.
186
187 =item (2)
188
189 The C<extends> keyword support multiple inheritance. Simply pass all
190 of your superclasses to C<extends> as a list:
191
192   extends 'Foo', 'Bar', 'Baz';
193
194 =item (3)
195
196 Moose supports using instance structures other than blessed hash
197 references (such as in a glob reference - see
198 L<MooseX::GlobRef::Object>).
199
200 =back
201
202 =head1 SEE ALSO
203
204 =over 4
205
206 =item Method Modifiers
207
208 The concept of method modifiers is directly ripped off from CLOS. A 
209 great explanation of them can be found by following this link.
210
211 L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>
212
213 =back
214
215 =head1 AUTHOR
216
217 Stevan Little E<lt>stevan@iinteractive.comE<gt>
218
219 =head1 COPYRIGHT AND LICENSE
220
221 Copyright 2006-2008 by Infinity Interactive, Inc.
222
223 L<http://www.iinteractive.com>
224
225 This library is free software; you can redistribute it and/or modify
226 it under the same terms as Perl itself.
227
228 =cut