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