rudementary support for attribute traits
[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
54provides (see L<Moose::Object> for details). However, you don't
cdcae970 55actually I<have> to inherit from L<Moose::Object> if you don't
a9eca7df 56want to. All Moose features will still be accessible to you.
cdcae970 57
58Now, onto the keywords. The first one we see here is C<has>, which
a9eca7df 59defines an instance attribute in your class:
cdcae970 60
61 has 'x' => (isa => 'Int', is => 'ro');
62
a9eca7df 63This will create an attribute named C<x>, which will expect the
cdcae970 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
a9eca7df 68The next C<has> line is very similar, with only one difference:
cdcae970 69
70 has 'y' => (isa => 'Int', is => 'rw');
71
a9eca7df 72A read/write (abbreviated as C<rw>) accessor will be generated for
73the C<y> attribute.
cdcae970 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
a9eca7df 108A small digression here: both Moose and C<extends> support multiple
4711f5f7 109inheritance. You simply pass all the superclasses to C<extends>,
cdcae970 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
a4e516f6 122broken object encapsulation) that C<z> is a private attribute.
cdcae970 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,
a9eca7df 150and get the same results again. Here is how that would look:
cdcae970 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
a9eca7df 162Now, of course, what use is a class if you can't instantiate objects
163with it? Since B<Point> inherits from L<Moose::Object>, it will also
164inherit the default L<Moose::Object> constructor: C<new>. Here
cdcae970 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
4711f5f7 181I hope this recipe has given you some explanation of how to use
a9eca7df 182Moose to build your Perl 5 classes. The next recipe will build upon
cdcae970 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
a9eca7df 193C<Int> is one. For more information on the builtin type constraints
cdcae970 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
a9eca7df 200structures such as blessed ARRAY refs and such. If you want your
201Moose classes to be interchangeable, it is advisable to avoid
202direct instance access, like that shown above.
cdcae970 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
4711f5f7 213great explanation of them can be found by following this link.
cdcae970 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
778db3ac 225Copyright 2006-2008 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