6 Moose::Cookbook::Recipe1 - The (always classic) B<Point> example.
13 has 'x' => (isa => 'Int', is => 'ro');
14 has 'y' => (isa => 'Int', is => 'rw');
27 has 'z' => (isa => 'Int');
29 after 'clear' => sub {
36 This is the classic Point example. This one in particular I took
37 from the Perl 6 Apocalypse 12 document, but it is similar to the
38 example found in the classic K&R C book as well, and many other
39 places. And now, onto the code:
41 As with all Perl 5 classes, a Moose class is defined in a package.
42 Moose now handles turning C<strict> and C<warnings> on for you, so
43 all you need do is say C<use Moose>, and no kittens will die.
45 By loading Moose, we are enabling the Moose "environment" to be
46 loaded within our package. This means that we export some functions
47 which serve as Moose "keywords". This is nothing fancier than that,
48 just plain old exported functions.
50 Another important thing happens at this stage as well. Moose will
51 automatically set your package's superclass to be L<Moose::Object>.
52 The reason we do this, is so that we can be sure that you will
53 inherit from L<Moose::Object> and get the benefits that provides
54 (see the L<Moose::Object> for those details). However, you don't
55 actually I<have> to inherit from L<Moose::Object> if you don't
56 want to, all other features of Moose are still accessible to you.
58 Now, onto the keywords. The first one we see here is C<has>, which
59 defines an instance attribute in your class.
61 has 'x' => (isa => 'Int', is => 'ro');
63 This will create an attribute named C<x>, it will expect that the
64 value stored in the attribute to pass the type constraint C<Int> (1),
65 and the accessor generated for this attribute will be read-only
66 (abbreviated as C<ro>).
68 The next C<has> line is very similar, with only one difference.
70 has 'y' => (isa => 'Int', is => 'rw');
72 For the C<y> attribute a read/write accessor will be generated
73 (abbreviated as C<rw>).
75 At this point the attributes have been defined, and it is time to
76 define our methods. In Moose, as with regular Perl 5 OO, a method
77 is just a subroutine defined within the package. So here we create
86 It is pretty standard, the only thing to note is that we are directly
87 accessing the C<x> slot in the instance L<(2)>. This is because the
88 value was created with a read-only accessor. This also shows that Moose
89 objects are not anything out of the ordinary, but just regular old
90 blessed HASH references. This means they are very compatible with
91 other Perl 5 (non-Moose) classes as well.
93 The next part of the code to review is the B<Point> subclass,
94 B<Point3D>. The first item you might notice is that we do not use
95 the standard C<use base> declaration here. Instead we use the Moose
96 keyword C<extends> like so:
100 This keyword will function very much like C<use base> does in that
101 it will make an attempt to load your class if it has not already been
102 loaded. However, it differs on one important point. The C<extends>
103 keyword will overwrite any previous values in your package's C<@ISA>,
104 where C<use base> will C<push> values onto the package's C<@ISA>. It
105 is my opinion that the behavior of C<extends> is more intuitive in
106 that it is more explicit about defining the superclass relationship.
108 A small digression here, both Moose and C<extends> support multiple
109 inheritance. You simply pass all the superclasses to C<extends>,
112 extends 'Foo', 'Bar', 'Baz';
114 Now, back to our B<Point3D> class. The next thing we do is to create
115 a new attribute for B<Point3D> called C<z>.
117 has 'z' => (isa => 'Int');
119 As with B<Point>'s C<x> and C<y> attributes, this attribute has a
120 type constraint of C<Int>, but it differs in that it does B<not>
121 ask for any autogenerated accessors. The result being (aside from
122 breaking object encapsulation), that C<x> is a private attribute.
124 Next comes another Moose feature which we call method "modifiers"
125 (or method "advice" for the AOP inclined). The modifier used here
126 is the C<after> modifier, and looks like this:
128 after 'clear' => sub {
133 This modifier tells Moose to install a C<clear> method for
134 B<Point3D> that will first run the C<clear> method for the
135 superclass (in this case C<Point::clear>), and then run this
136 method I<after> it (passing in the same arguments as the original
139 Now, of course using the C<after> modifier is not the only way to
140 accomplish this. I mean, after all, this B<is> Perl right? You
141 would get the same results with this code:
145 $self->SUPER::clear();
149 You could also use another Moose method modifier, C<override> here,
150 and get the same results again. Here is how that would look.
152 override 'clear' => sub {
158 The C<override> modifier allows you to use the C<super> keyword
159 within it to dispatch to the superclass's method in a very Ruby-ish
162 Now of course, what use is a class if you cant instantiate objects
163 with it. Now since B<Point> inherits from L<Moose::Object>, it will
164 inherit the default L<Moose::Object> constructor called C<new>. Here
165 are two examples of how that is used:
167 my $point = Point->new(x => 1, y => 2);
168 my $point3d = Point3D->new(x => 1, y => 2, z => 3);
170 As you can see, C<new> accepts named argument pairs for any of the
171 attributes. It does not I<require> that you pass in the all the
172 attributes, and it will politely ignore any named arguments it does
175 From here on, you can use C<$point> and C<$point3d> just as you would
176 any other Perl 5 object. For a more detailed example of what can be
177 done, you can refer to the F<t/001_recipe.t> test file.
181 I hope this recipe has given you some explanation of how to use
182 Moose to build you Perl 5 classes. The next recipe will build upon
183 the basics shown here with more complex attributes and methods.
192 Several default type constraints are provided by Moose, of which
193 C<Int> is one. For more information on the built-in type constraints
194 and the type constraint system in general, see the
195 L<Moose::Util::TypeConstraints> documentation.
199 Future plans for Moose include allowing for alternate instance
200 structures such as blessed ARRAY refs and such. If you want you Moose
201 classes to be interchangeable, it is advised that you avoid direct
202 instance access, like that which is shown above.
210 =item Method Modifiers
212 The concept of method modifiers is directly ripped off from CLOS. A
213 great explanation of them can be found by following this link.
215 L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>
221 Stevan Little E<lt>stevan@iinteractive.comE<gt>
223 =head1 COPYRIGHT AND LICENSE
225 Copyright 2006, 2007 by Infinity Interactive, Inc.
227 L<http://www.iinteractive.com>
229 This library is free software; you can redistribute it and/or modify
230 it under the same terms as Perl itself.