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