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 on C<strict> and C<warnings> for you, so
43 all you need to do is say C<use Moose>, and no kittens will die.
45 By loading Moose, we are enabling the loading of the Moose
46 "environment" into our package. This means that we import some
47 functions which serve as Moose "keywords". These aren't anything
48 fancy, 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 your class
53 will inherit from L<Moose::Object> and get the benefits that
54 provides (such as a constructor; see L<Moose::Object> for details).
55 However, you don't actually I<have> to inherit from L<Moose::Object>
56 if you don't want to. All Moose features will still be accessible to
59 Now, onto the keywords. The first one we see here is C<has>, which
60 defines an instance attribute in your class:
62 has 'x' => (isa => 'Int', is => 'ro');
64 This will create an attribute named C<x>, which will expect the
65 value stored in the attribute to pass the type constraint C<Int> (1),
66 and the accessor generated for this attribute will be read-only
67 (abbreviated as C<ro>).
69 The next C<has> line is very similar, with only one difference:
71 has 'y' => (isa => 'Int', is => 'rw');
73 A read/write (abbreviated as C<rw>) accessor will be generated for
76 At this point the attributes have been defined, and it is time to
77 define our methods. In Moose, as with regular Perl 5 OO, a method
78 is just a subroutine defined within the package. So here we create
87 It is pretty standard, the only thing to note is that we are directly
88 accessing the C<x> slot in the instance L<(2)>. This is because the
89 value was created with a read-only accessor. This also shows that Moose
90 objects are not anything out of the ordinary, but just regular old
91 blessed HASH references. This means they are very compatible with
92 other Perl 5 (non-Moose) classes as well.
94 The next part of the code to review is the B<Point> subclass,
95 B<Point3D>. The first item you might notice is that we do not use
96 the standard C<use base> declaration here. Instead we use the Moose
97 keyword C<extends> like so:
101 This keyword will function very much like C<use base> does in that
102 it will make an attempt to load your class if it has not already been
103 loaded. However, it differs on one important point. The C<extends>
104 keyword will overwrite any previous values in your package's C<@ISA>,
105 where C<use base> will C<push> values onto the package's C<@ISA>. It
106 is my opinion that the behavior of C<extends> is more intuitive in
107 that it is more explicit about defining the superclass relationship.
109 A small digression here: both Moose and C<extends> support multiple
110 inheritance. You simply pass all the superclasses to C<extends>,
113 extends 'Foo', 'Bar', 'Baz';
115 Now, back to our B<Point3D> class. The next thing we do is to create
116 a new attribute for B<Point3D> called C<z>.
118 has 'z' => (isa => 'Int');
120 As with B<Point>'s C<x> and C<y> attributes, this attribute has a
121 type constraint of C<Int>, but it differs in that it does B<not>
122 ask for any autogenerated accessors. The result being (aside from
123 broken object encapsulation) that C<z> is a private attribute.
125 Next comes another Moose feature which we call method "modifiers"
126 (or method "advice" for the AOP inclined). The modifier used here
127 is the C<after> modifier, and looks like this:
129 after 'clear' => sub {
134 This modifier tells Moose to install a C<clear> method for
135 B<Point3D> that will first run the C<clear> method for the
136 superclass (in this case C<Point::clear>), and then run this
137 method I<after> it (passing in the same arguments as the original
140 Now, of course using the C<after> modifier is not the only way to
141 accomplish this. I mean, after all, this B<is> Perl right? You
142 would get the same results with this code:
146 $self->SUPER::clear();
150 You could also use another Moose method modifier, C<override> here,
151 and get the same results again. Here is how that would look:
153 override 'clear' => sub {
159 The C<override> modifier allows you to use the C<super> keyword
160 within it to dispatch to the superclass's method in a very Ruby-ish
163 Now, of course, what use is a class if you can't instantiate objects
164 with it? Since B<Point> inherits from L<Moose::Object>, it will also
165 inherit the default L<Moose::Object> constructor: C<new>. Here
166 are two examples of how that is used:
168 my $point = Point->new(x => 1, y => 2);
169 my $point3d = Point3D->new(x => 1, y => 2, z => 3);
171 As you can see, C<new> accepts named argument pairs for any of the
172 attributes. It does not I<require> that you pass in the all the
173 attributes, and it will politely ignore any named arguments it does
176 From here on, you can use C<$point> and C<$point3d> just as you would
177 any other Perl 5 object. For a more detailed example of what can be
178 done, you can refer to the F<t/000_recipes/001_recipe.t> test file.
182 I hope this recipe has given you some explanation of how to use
183 Moose to build your Perl 5 classes. The next recipe will build upon
184 the basics shown here with more complex attributes and methods.
193 Several default type constraints are provided by Moose, of which
194 C<Int> is one. For more information on the builtin type constraints
195 and the type constraint system in general, see the
196 L<Moose::Util::TypeConstraints> documentation.
200 Moose supports using instance structures other than blessed hash
201 references (such as in a glob reference -- see
202 L<MooseX::GlobRef::Object>). If you want your Moose classes to
203 be interchangeable, it is advisable to avoid direct instance
204 access, like that shown above. Moose does let you get and set
205 attributes directly without exposing the instance structure, but
206 that's an advanced topic (intrepid readers should refer to the
207 L<Moose::Meta::Attribute documentation>).
215 =item Method Modifiers
217 The concept of method modifiers is directly ripped off from CLOS. A
218 great explanation of them can be found by following this link.
220 L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>
226 Stevan Little E<lt>stevan@iinteractive.comE<gt>
228 =head1 COPYRIGHT AND LICENSE
230 Copyright 2006-2008 by Infinity Interactive, Inc.
232 L<http://www.iinteractive.com>
234 This library is free software; you can redistribute it and/or modify
235 it under the same terms as Perl itself.