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