Dzil-ize all the .pod files so they can be pod-woven
[gitmo/Moose.git] / lib / Moose / Manual / MethodModifiers.pod
CommitLineData
daa0fd7d 1package Moose::Manual::MethodModifiers;
2
3# ABSTRACT: Moose's method modifiers
92cd015f 4
daa0fd7d 5__END__
92cd015f 6
daa0fd7d 7=pod
92cd015f 8
9=head1 WHAT IS A METHOD MODIFIER?
10
646e0fb0 11Moose provides a feature called "method modifiers". You can also think
12of these as "hooks" or "advice".
92cd015f 13
14It's probably easiest to understand this feature with a few examples:
15
16 package Example;
17
18 use Moose;
19
20 sub foo {
909103e1 21 print " foo\n";
92cd015f 22 }
23
24 before 'foo' => sub { print "about to call foo\n"; };
08f950aa 25 after 'foo' => sub { print "just called foo\n"; };
92cd015f 26
27 around 'foo' => sub {
28 my $orig = shift;
29 my $self = shift;
30
909103e1 31 print " I'm around foo\n";
92cd015f 32
33 $self->$orig(@_);
34
909103e1 35 print " I'm still around foo\n";
92cd015f 36 };
37
38Now if I call C<< Example->new->foo >> I'll get the following output:
39
40 about to call foo
909103e1 41 I'm around foo
42 foo
43 I'm still around foo
92cd015f 44 just called foo
45
46You probably could have figured that out from the names "before",
47"after", and "around".
48
49Also, as you can see, the before modifiers come before around
50modifiers, and after modifiers come last.
51
52When there are multiple modifiers of the same type, the before and
53around modifiers run from the last added to the first, and after
54modifiers run from first added to last:
55
56 before 2
57 before 1
58 around 2
59 around 1
60 primary
61 around 1
62 around 2
63 after 1
64 after 2
65
66=head1 WHY USE THEM?
67
909103e1 68Method modifiers have many uses. They are often used in roles to alter the
69behavior of methods in the classes that consume the role. See
70L<Moose::Manual::Roles> for more information about roles.
92cd015f 71
dab94063 72Since modifiers are mostly useful in roles, some of the examples below
73are a bit artificial. They're intended to give you an idea of how
74modifiers work, but may not be the most natural usage.
92cd015f 75
76=head1 BEFORE, AFTER, AND AROUND
77
dab94063 78Method modifiers can be used to add behavior to a method that Moose
79generates for you, such as an attribute accessor:
92cd015f 80
81 has 'size' => ( is => 'rw' );
82
83 before 'size' => sub {
84 my $self = shift;
85
86 if (@_) {
87 Carp::cluck('Someone is setting size');
88 }
89 };
90
91Another use for the before modifier would be to do some sort of
6549b0d1 92prechecking on a method call. For example:
92cd015f 93
94 before 'size' => sub {
95 my $self = shift;
96
97 die 'Cannot set size while the person is growing'
98 if @_ && $self->is_growing;
99 };
100
646e0fb0 101This lets us implement logical checks that don't make sense as type
102constraints. In particular, they're useful for defining logical rules
103about an object's state changes.
92cd015f 104
105Similarly, an after modifier could be used for logging an action that
106was taken.
107
108Note that the return values of both before and after modifiers are
109ignored.
110
909103e1 111An around modifier is more powerful than either a before or
646e0fb0 112after modifier. It can modify the arguments being passed to the
113original method, and you can even decide to simply not call the
dab94063 114original method at all. You can also modify the return value with an
115around modifier.
92cd015f 116
117An around modifier receives the original method as its first argument,
118I<then> the object, and finally any arguments passed to the method.
119
120 around 'size' => sub {
121 my $orig = shift;
122 my $self = shift;
123
124 return $self->$orig()
125 unless @_;
126
127 my $size = shift;
128 $size = $size / 2
129 if $self->likes_small_things();
130
131 return $self->$orig($size);
132 };
133
78946cf8 134C<before>, C<after>, and C<around> can also modify multiple methods
135at once. The simplest example of this is passing them as a list:
136
909103e1 137 before [qw(foo bar baz)] => sub {
78946cf8 138 warn "something is being called!";
139 };
140
141This will add a C<before> modifier to each of the C<foo>, C<bar>,
142and C<baz> methods in the current class, just as though a separate
143call to C<before> was made for each of them. The list can be passed
144either as a bare list, or as an arrayref. Note that the name of the
145function being modified isn't passed in in any way; this syntax is
146only intended for cases where the function being modified doesn't
909103e1 147actually matter. If the function name does matter, use something like this:
78946cf8 148
149 for my $func (qw(foo bar baz)) {
150 before $func => sub {
151 warn "$func was called!";
152 };
153 }
154
78946cf8 155In addition, you can specify a regular expression to indicate the
156methods to wrap, like so:
157
158 after qr/^command_/ => sub {
159 warn "got a command";
160 };
161
162This will match the regular expression against each method name
163returned by L<Class::MOP::Class/get_method_list>, and add a modifier
909103e1 164to each one that matches. The same caveats apply as above. Using regular
78946cf8 165expressions to determine methods to wrap is quite a bit more powerful
166than the previous alternatives, but it's also quite a bit more
167dangerous. In particular, you should make sure to avoid wrapping
909103e1 168methods with a special meaning to Moose or Perl, such as C<meta>, C<new>,
78946cf8 169C<BUILD>, C<DESTROY>, C<AUTOLOAD>, etc., as this could cause
170unintended (and hard to debug) problems.
171
92cd015f 172=head1 INNER AND AUGMENT
173
174Augment and inner are two halves of the same feature. The augment
175modifier provides a sort of inverted subclassing. You provide part of
176the implementation in a superclass, and then document that subclasses
177are expected to provide the rest.
178
179The superclass calls C<inner()>, which then calls the C<augment>
180modifier in the subclass:
181
182 package Document;
183
184 use Moose;
185
186 sub as_xml {
187 my $self = shift;
188
189 my $xml = "<document>\n";
190 $xml .= inner();
191 $xml .= "</document>\n";
192
193 return $xml;
194 }
195
196Using C<inner()> in this method makes it possible for one or more
197subclasses to then augment this method with their own specific
198implementation:
199
200 package Report;
201
202 use Moose;
203
204 extends 'Document';
205
206 augment 'as_xml' => sub {
207 my $self = shift;
208
909103e1 209 my $xml = " <report>\n";
92cd015f 210 $xml .= inner();
909103e1 211 $xml .= " </report>\n";
92cd015f 212
213 return $xml;
214 };
215
216When we call C<as_xml> on a Report object, we get something like this:
217
218 <document>
909103e1 219 <report>
220 </report>
92cd015f 221 </document>
222
223But we also called C<inner()> in C<Report>, so we can continue
224subclassing and adding more content inside the document:
225
226 package Report::IncomeAndExpenses;
227
228 use Moose;
229
230 extends 'Report';
231
232 augment 'as_xml' => sub {
233 my $self = shift;
234
909103e1 235 my $xml = ' <income>' . $self->income . '</income>';
92cd015f 236 $xml .= "\n";
909103e1 237 $xml .= ' <expenses>' . $self->expenses . '</expenses>';
92cd015f 238 $xml .= "\n";
239
240 $xml .= inner() || q{};
241
242 return $xml;
243 };
244
245Now our report has some content:
246
247 <document>
909103e1 248 <report>
249 <income>$10</income>
250 <expenses>$8</expenses>
251 </report>
92cd015f 252 </document>
253
254What makes this combination of C<augment> and C<inner()> special is
ce5e6e3c 255that it allows us to have methods which are called from parent (least
646e0fb0 256specific) to child (most specific). This inverts the normal
257inheritance pattern.
92cd015f 258
909103e1 259Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If the
260object is an instance of C<Report::IncomeAndExpenses> then this call is a
261no-op, and just returns false. It's a good idea to always call C<inner()> to
262allow for future subclassing.
92cd015f 263
264=head1 OVERRIDE AND SUPER
265
266Finally, Moose provides some simple sugar for Perl's built-in method
267overriding scheme. If you want to override a method from a parent
268class, you can do this with C<override>:
269
270 package Employee;
271
272 use Moose;
273
274 extends 'Person';
275
276 has 'job_title' => ( is => 'rw' );
277
278 override 'display_name' => sub {
279 my $self = shift;
280
281 return super() . q{, } . $self->title();
282 };
283
284The call to C<super()> is almost the same as calling C<<
285$self->SUPER::display_name >>. The difference is that the arguments
286passed to the superclass's method will always be the same as the ones
287passed to the method modifier, and cannot be changed.
288
289All arguments passed to C<super()> are ignored, as are any changes
290made to C<@_> before C<super()> is called.
291
292=head1 SEMI-COLONS
293
294Because all of these method modifiers are implemented as Perl
295functions, you must always end the modifier declaration with a
296semi-colon:
297
298 after 'foo' => sub { };
299
92cd015f 300=cut