Commit | Line | Data |
471c4f09 |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
021b8139 |
6 | Moose::Cookbook::Basics::Recipe1 - The (always classic) B<Point> example. |
471c4f09 |
7 | |
8 | =head1 SYNOPSIS |
9 | |
10 | package Point; |
471c4f09 |
11 | use Moose; |
a34602e7 |
12 | |
13 | has 'x' => (isa => 'Int', is => 'rw', required => 1); |
14 | has 'y' => (isa => 'Int', is => 'rw', required => 1); |
15 | |
471c4f09 |
16 | sub clear { |
17 | my $self = shift; |
a34602e7 |
18 | $self->x(0); |
19 | $self->y(0); |
471c4f09 |
20 | } |
a34602e7 |
21 | |
471c4f09 |
22 | package Point3D; |
471c4f09 |
23 | use Moose; |
a34602e7 |
24 | |
471c4f09 |
25 | extends 'Point'; |
a34602e7 |
26 | |
27 | has 'z' => (isa => 'Int', is => 'rw', required => 1); |
28 | |
471c4f09 |
29 | after 'clear' => sub { |
30 | my $self = shift; |
a34602e7 |
31 | $self->z(0); |
471c4f09 |
32 | }; |
33 | |
34 | =head1 DESCRIPTION |
35 | |
a34602e7 |
36 | This is the classic Point example. It is taken directly from the Perl |
37 | 6 Apocalypse 12 document, and is similar to the example found in the |
38 | classic K&R C book as well. |
cdcae970 |
39 | |
a34602e7 |
40 | As with all Perl 5 classes, a Moose class is defined in a package. |
41 | Moose handles turning on C<strict> and C<warnings> for us, so all we |
42 | need to do is say C<use Moose>, and no kittens will die. |
cdcae970 |
43 | |
a34602e7 |
44 | When Moose is loaded, it exports a set of sugar functions into our |
45 | package. This means that we import some functions which serve as Moose |
46 | "keywords". These aren't real language keywords, they're just Perl |
47 | functions exported into our package. |
cdcae970 |
48 | |
a34602e7 |
49 | Moose automatically makes our package a subclass of L<Moose::Object>. |
50 | The L<Moose::Object> class provides us with a constructor that |
51 | respects our attributes, as well other features. See L<Moose::Object> |
52 | for details. |
cdcae970 |
53 | |
a34602e7 |
54 | Now, onto the keywords. The first one we see here is C<has>, which |
55 | defines an instance attribute in our class: |
cdcae970 |
56 | |
a34602e7 |
57 | has 'x' => (isa => 'Int', is => 'rw', required => 1); |
cdcae970 |
58 | |
a34602e7 |
59 | This will create an attribute named C<x>. The C<isa> parameter says |
60 | that we expect the value stored in this attribute to pass the type |
61 | constraint for C<Int> (1). The accessor generated for this attribute |
62 | will be read-write. |
cdcae970 |
63 | |
a34602e7 |
64 | The C<< requires => 1 >> parameter means that this attribute must be |
65 | provided when a new object is created. A point object without |
66 | coordinates doesn't make much sense, so we don't allow it. |
cdcae970 |
67 | |
a34602e7 |
68 | We have defined our attributes; next we define our methods. In Moose, |
69 | as with regular Perl 5 OO, a method is just a subroutine defined |
70 | within the package: |
cdcae970 |
71 | |
72 | sub clear { |
73 | my $self = shift; |
a34602e7 |
74 | $self->x(0); |
75 | $self->y(0); |
cdcae970 |
76 | } |
77 | |
a34602e7 |
78 | That concludes the B<Point> class. |
cdcae970 |
79 | |
a34602e7 |
80 | Next we have a subclass of B<Point>, B<Point3D>. To declare our |
81 | superclass, we use the Moose keyword C<extends>: |
cdcae970 |
82 | |
83 | extends 'Point'; |
84 | |
a34602e7 |
85 | The C<extends> keyword works much like C<use base>. First, it will |
86 | attempt to load your class if needed. However, unlike C<base>, the |
87 | C<extends> keyword will I<overwrite> any previous values in your |
88 | package's C<@ISA>, where C<use base> will C<push> values onto the |
89 | package's C<@ISA>. |
cdcae970 |
90 | |
a34602e7 |
91 | It is my opinion that the behavior of C<extends> is more intuitive. |
92 | (2). |
cdcae970 |
93 | |
a34602e7 |
94 | Next we create a new attribute for B<Point3D> called C<z>. |
cdcae970 |
95 | |
a34602e7 |
96 | has 'z' => (isa => 'Int', is => 'rw', required => 1); |
cdcae970 |
97 | |
a34602e7 |
98 | This attribute is just like B<Point>'s C<x> and C<y> attributes. |
cdcae970 |
99 | |
a34602e7 |
100 | The C<after> keyword demonstrates a Moose feature called "method |
101 | modifiers" (or "advice" for the AOP inclined): |
cdcae970 |
102 | |
103 | after 'clear' => sub { |
104 | my $self = shift; |
a34602e7 |
105 | $self->z(0); |
cdcae970 |
106 | }; |
107 | |
a34602e7 |
108 | When C<clear> is called on a B<Point3D> object, our modifier method |
109 | gets called as well. Unsurprisingly, the modifier is called I<after> |
110 | the real method. |
111 | |
112 | In this case, the real C<clear> method is inherited from B<Point>. Our |
113 | modifier method receives the same arguments as those passed to the |
114 | modified method (just C<$self> here). |
cdcae970 |
115 | |
a34602e7 |
116 | Of course, using the C<after> modifier is not the only way to |
117 | accomplish this. This B<is> Perl, right? You can get the same results |
118 | with this code: |
cdcae970 |
119 | |
120 | sub clear { |
121 | my $self = shift; |
122 | $self->SUPER::clear(); |
a34602e7 |
123 | $self->z(0); |
cdcae970 |
124 | } |
125 | |
a34602e7 |
126 | You could also use another Moose method modifier, C<override>: |
cdcae970 |
127 | |
128 | override 'clear' => sub { |
129 | my $self = shift; |
130 | super(); |
a34602e7 |
131 | $self->z(0); |
cdcae970 |
132 | }; |
cdcae970 |
133 | |
a34602e7 |
134 | The C<override> modifier allows you to use the C<super> keyword to |
135 | dispatch to the superclass's method in a very Ruby-ish style. |
cdcae970 |
136 | |
a34602e7 |
137 | The choice of whether to use a method modifier, and which one to use, |
138 | is often a question of style as much as functionality. |
139 | |
140 | Since B<Point> inherits from L<Moose::Object>, it will also inherit |
141 | the default L<Moose::Object> constructor: |
142 | |
143 | my $point = Point ->new(x => 1, y => 2); |
cdcae970 |
144 | my $point3d = Point3D->new(x => 1, y => 2, z => 3); |
145 | |
a34602e7 |
146 | The C<new> constructor accepts a named argument pair for each |
147 | attribute defined by the class. In this particular example, the |
148 | attributes are required, and calling C<new> without them will throw an |
149 | error. |
150 | |
151 | From here on, we can use C<$point> and C<$point3d> just as you would |
152 | any other Perl 5 object. For a more detailed example of what can be |
153 | done, you can refer to the F<t/000_recipes/basic/001_point.t> test |
154 | file. |
155 | |
156 | =head2 Moose Objects are Just Hashrefs |
157 | |
158 | While this all may appear rather magical, it's important to realize |
159 | that Moose objects are just hash references under the hood (3). For |
160 | example, you could pass C<$self> to C<Data::Dumper> and you'd get |
161 | exactly what you'd expect. |
cdcae970 |
162 | |
a34602e7 |
163 | You could even poke around inside the object's data structure, but |
164 | that is strongly discouraged. |
165 | |
166 | The fact that Moose objects are hashrefs means it is easy to use Moose |
167 | to extend non-Moose classes, as long as they too are hash |
168 | references. If you want to extend a non-hashref class, check out |
169 | C<MooseX::InsideOut>. |
cdcae970 |
170 | |
171 | =head1 CONCLUSION |
172 | |
a34602e7 |
173 | This recipe demonstrates some basic Moose concepts. The next recipe |
174 | will build upon the basics shown here with more complex attributes and |
175 | methods. Please read on :) |
cdcae970 |
176 | |
177 | =head1 FOOTNOTES |
178 | |
179 | =over 4 |
180 | |
181 | =item (1) |
182 | |
a34602e7 |
183 | Moose provides a number of builtin type constraints are provided by, |
184 | of which C<Int> is one. For more information on the type constraint |
185 | system, see L<Moose::Util::TypeConstraints>. |
cdcae970 |
186 | |
187 | =item (2) |
188 | |
a34602e7 |
189 | The C<extends> keyword support multiple inheritance. Simply pass all |
190 | of your superclasses to C<extends> as a list: |
191 | |
192 | extends 'Foo', 'Bar', 'Baz'; |
193 | |
194 | =item (3) |
195 | |
1eca36fc |
196 | Moose supports using instance structures other than blessed hash |
a34602e7 |
197 | references (such as in a glob reference - see |
198 | L<MooseX::GlobRef::Object>). |
cdcae970 |
199 | |
200 | =back |
201 | |
202 | =head1 SEE ALSO |
203 | |
204 | =over 4 |
205 | |
206 | =item Method Modifiers |
207 | |
208 | The concept of method modifiers is directly ripped off from CLOS. A |
4711f5f7 |
209 | great explanation of them can be found by following this link. |
cdcae970 |
210 | |
211 | L<http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html> |
212 | |
213 | =back |
214 | |
471c4f09 |
215 | =head1 AUTHOR |
216 | |
217 | Stevan Little E<lt>stevan@iinteractive.comE<gt> |
218 | |
219 | =head1 COPYRIGHT AND LICENSE |
220 | |
778db3ac |
221 | Copyright 2006-2008 by Infinity Interactive, Inc. |
471c4f09 |
222 | |
223 | L<http://www.iinteractive.com> |
224 | |
225 | This library is free software; you can redistribute it and/or modify |
226 | it under the same terms as Perl itself. |
227 | |
a34602e7 |
228 | =cut |