6 Moose::Cookbook::Recipe1 - The (always classic) B<Point> example.
13 has 'x' => (isa => 'Int', is => 'ro', clearer => 'clear_x' );
14 has 'y' => (isa => 'Int', is => 'rw', clearer => 'clear_y');
19 $self->clear_y(); # or $self->y(0);
33 has 'z' => (isa => 'Int');
35 after 'clear' => sub {
42 This is the classic Point example. This one in particular I took
43 from the Perl 6 Apocalypse 12 document, but it is similar to the
44 example found in the classic K&R C book as well, and many other
45 places. And now, onto the code:
47 As with all Perl 5 classes, a Moose class is defined in a package.
48 Moose now handles turning on C<strict> and C<warnings> for you, so
49 all you need to do is say C<use Moose>, and no kittens will die.
51 By loading Moose, we are enabling the loading of the Moose
52 "environment" into our package. This means that we import some
53 functions which serve as Moose "keywords". These aren't anything
54 fancy, just plain old exported functions.
56 Another important thing happens at this stage as well. Moose will
57 automatically set your package's superclass to be L<Moose::Object>.
58 The reason we do this, is so that we can be sure that your class
59 will inherit from L<Moose::Object> and get the benefits that
60 provides (see L<Moose::Object> for details). However, you don't
61 actually I<have> to inherit from L<Moose::Object> if you don't
62 want to. All Moose features will still be accessible to you.
64 Now, onto the keywords. The first one we see here is C<has>, which
65 defines an instance attribute in your class:
67 has 'x' => (isa => 'Int', is => 'ro');
69 This will create an attribute named C<x>, which will expect the
70 value stored in the attribute to pass the type constraint C<Int> (1),
71 and the accessor generated for this attribute will be read-only
72 (abbreviated as C<ro>).
74 The next C<has> line is very similar, with only one difference:
76 has 'y' => (isa => 'Int', is => 'rw');
78 A read/write (abbreviated as C<rw>) accessor will be generated for
81 At this point the attributes have been defined, and it is time to
82 define our methods. In Moose, as with regular Perl 5 OO, a method
83 is just a subroutine defined within the package. So here we create
92 It is pretty standard, the only thing to note is that we are directly
93 accessing the C<x> slot in the instance L<(2)>. This is because the
94 value was created with a read-only accessor. This also shows that Moose
95 objects are not anything out of the ordinary, but just regular old
96 blessed HASH references. This means they are very compatible with
97 other Perl 5 (non-Moose) classes as well.
99 The next part of the code to review is the B<Point> subclass,
100 B<Point3D>. The first item you might notice is that we do not use
101 the standard C<use base> declaration here. Instead we use the Moose
102 keyword C<extends> like so:
106 This keyword will function very much like C<use base> does in that
107 it will make an attempt to load your class if it has not already been
108 loaded. However, it differs on one important point. The C<extends>
109 keyword will overwrite any previous values in your package's C<@ISA>,
110 where C<use base> will C<push> values onto the package's C<@ISA>. It
111 is my opinion that the behavior of C<extends> is more intuitive in
112 that it is more explicit about defining the superclass relationship.
114 A small digression here: both Moose and C<extends> support multiple
115 inheritance. You simply pass all the superclasses to C<extends>,
118 extends 'Foo', 'Bar', 'Baz';
120 Now, back to our B<Point3D> class. The next thing we do is to create
121 a new attribute for B<Point3D> called C<z>.
123 has 'z' => (isa => 'Int');
125 As with B<Point>'s C<x> and C<y> attributes, this attribute has a
126 type constraint of C<Int>, but it differs in that it does B<not>
127 ask for any autogenerated accessors. The result being (aside from
128 broken object encapsulation) that C<x> is a private attribute.
130 Next comes another Moose feature which we call method "modifiers"
131 (or method "advice" for the AOP inclined). The modifier used here
132 is the C<after> modifier, and looks like this:
134 after 'clear' => sub {
139 This modifier tells Moose to install a C<clear> method for
140 B<Point3D> that will first run the C<clear> method for the
141 superclass (in this case C<Point::clear>), and then run this
142 method I<after> it (passing in the same arguments as the original
145 Now, of course using the C<after> modifier is not the only way to
146 accomplish this. I mean, after all, this B<is> Perl right? You
147 would get the same results with this code:
151 $self->SUPER::clear();
155 You could also use another Moose method modifier, C<override> here,
156 and get the same results again. Here is how that would look:
158 override 'clear' => sub {
164 The C<override> modifier allows you to use the C<super> keyword
165 within it to dispatch to the superclass's method in a very Ruby-ish
168 Now, of course, what use is a class if you can't instantiate objects
169 with it? Since B<Point> inherits from L<Moose::Object>, it will also
170 inherit the default L<Moose::Object> constructor: C<new>. Here
171 are two examples of how that is used:
173 my $point = Point->new(x => 1, y => 2);
174 my $point3d = Point3D->new(x => 1, y => 2, z => 3);
176 As you can see, C<new> accepts named argument pairs for any of the
177 attributes. It does not I<require> that you pass in the all the
178 attributes, and it will politely ignore any named arguments it does
181 From here on, you can use C<$point> and C<$point3d> just as you would
182 any other Perl 5 object. For a more detailed example of what can be
183 done, you can refer to the F<t/001_recipe.t> test file.
187 I hope this recipe has given you some explanation of how to use
188 Moose to build your Perl 5 classes. The next recipe will build upon
189 the basics shown here with more complex attributes and methods.
198 Several default type constraints are provided by Moose, of which
199 C<Int> is one. For more information on the builtin type constraints
200 and the type constraint system in general, see the
201 L<Moose::Util::TypeConstraints> documentation.
205 Future plans for Moose include allowing for alternate instance
206 structures such as blessed ARRAY refs and such. If you want your
207 Moose classes to be interchangeable, it is advisable to avoid
208 direct instance access, like that shown above.
216 =item Method Modifiers
218 The concept of method modifiers is directly ripped off from CLOS. A
219 great explanation of them can be found by following this link.
221 L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>
227 Stevan Little E<lt>stevan@iinteractive.comE<gt>
229 =head1 COPYRIGHT AND LICENSE
231 Copyright 2006, 2007 by Infinity Interactive, Inc.
233 L<http://www.iinteractive.com>
235 This library is free software; you can redistribute it and/or modify
236 it under the same terms as Perl itself.