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