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