1 package Moose::Manual::MethodModifiers;
3 # ABSTRACT: Moose's method modifiers
9 =head1 WHAT IS A METHOD MODIFIER?
11 Moose provides a feature called "method modifiers". You can also think
12 of these as "hooks" or "advice".
14 It's probably easiest to understand this feature with a few examples:
24 before 'foo' => sub { print "about to call foo\n"; };
25 after 'foo' => sub { print "just called foo\n"; };
31 print " I'm around foo\n";
35 print " I'm still around foo\n";
38 Now if I call C<< Example->new->foo >> I'll get the following output:
46 You probably could have figured that out from the names "before",
47 "after", and "around".
49 Also, as you can see, the before modifiers come before around
50 modifiers, and after modifiers come last.
52 When there are multiple modifiers of the same type, the before and
53 around modifiers run from the last added to the first, and after
54 modifiers run from first added to last:
68 Method modifiers have many uses. They are often used in roles to alter the
69 behavior of methods in the classes that consume the role. See
70 L<Moose::Manual::Roles> for more information about roles.
72 Since modifiers are mostly useful in roles, some of the examples below
73 are a bit artificial. They're intended to give you an idea of how
74 modifiers work, but may not be the most natural usage.
76 =head1 BEFORE, AFTER, AND AROUND
78 Method modifiers can be used to add behavior to methods without modifying the definition of those methods.
80 =head2 BEFORE and AFTER modifiers
82 Method modifiers can be used to add behavior to a method that Moose
83 generates for you, such as an attribute accessor:
85 has 'size' => ( is => 'rw' );
87 before 'size' => sub {
91 Carp::cluck('Someone is setting size');
95 Another use for the before modifier would be to do some sort of
96 prechecking on a method call. For example:
98 before 'size' => sub {
101 die 'Cannot set size while the person is growing'
102 if @_ && $self->is_growing;
105 This lets us implement logical checks that don't make sense as type
106 constraints. In particular, they're useful for defining logical rules
107 about an object's state changes.
109 Similarly, an after modifier could be used for logging an action that
112 Note that the return values of both before and after modifiers are
115 =head2 AROUND modifiers
117 An around modifier is more powerful than either a before or
118 after modifier. It can modify the arguments being passed to the
119 original method, and you can even decide to simply not call the
120 original method at all. You can also modify the return value with an
123 An around modifier receives the original method as its first argument,
124 I<then> the object, and finally any arguments passed to the method.
126 around 'size' => sub {
130 return $self->$orig()
135 if $self->likes_small_things();
137 return $self->$orig($size);
140 =head2 Wrapping multiple methods at once
142 C<before>, C<after>, and C<around> can also modify multiple methods
143 at once. The simplest example of this is passing them as a list:
145 before [qw(foo bar baz)] => sub {
146 warn "something is being called!";
149 This will add a C<before> modifier to each of the C<foo>, C<bar>,
150 and C<baz> methods in the current class, just as though a separate
151 call to C<before> was made for each of them. The list can be passed
152 either as a bare list, or as an arrayref. Note that the name of the
153 function being modified isn't passed in in any way; this syntax is
154 only intended for cases where the function being modified doesn't
155 actually matter. If the function name does matter, use something like this:
157 for my $func (qw(foo bar baz)) {
158 before $func => sub {
159 warn "$func was called!";
163 =head2 Using regular expressions to select methods to wrap
165 In addition, you can specify a regular expression to indicate the
166 methods to wrap, like so:
168 after qr/^command_/ => sub {
169 warn "got a command";
172 This will match the regular expression against each method name
173 returned by L<Class::MOP::Class/get_method_list>, and add a modifier
174 to each one that matches. The same caveats apply as above.
176 Using regular expressions to determine methods to wrap is quite a bit more
177 powerful than the previous alternatives, but it's also quite a bit more
178 dangerous. Bear in mind that if your regular expression matches certain Perl
179 and Moose reserved method names with a special meaning to Moose or Perl, such
180 as C<meta>, C<new>, C<BUILD>, C<DESTROY>, C<AUTOLOAD>, etc, this could cause
181 unintended (and hard to debug) problems and is best avoided.
184 =head1 INNER AND AUGMENT
186 Augment and inner are two halves of the same feature. The augment
187 modifier provides a sort of inverted subclassing. You provide part of
188 the implementation in a superclass, and then document that subclasses
189 are expected to provide the rest.
191 The superclass calls C<inner()>, which then calls the C<augment>
192 modifier in the subclass:
201 my $xml = "<document>\n";
203 $xml .= "</document>\n";
208 Using C<inner()> in this method makes it possible for one or more
209 subclasses to then augment this method with their own specific
218 augment 'as_xml' => sub {
221 my $xml = " <report>\n";
223 $xml .= " </report>\n";
228 When we call C<as_xml> on a Report object, we get something like this:
235 But we also called C<inner()> in C<Report>, so we can continue
236 subclassing and adding more content inside the document:
238 package Report::IncomeAndExpenses;
244 augment 'as_xml' => sub {
247 my $xml = ' <income>' . $self->income . '</income>';
249 $xml .= ' <expenses>' . $self->expenses . '</expenses>';
252 $xml .= inner() || q{};
257 Now our report has some content:
262 <expenses>$8</expenses>
266 What makes this combination of C<augment> and C<inner()> special is
267 that it allows us to have methods which are called from parent (least
268 specific) to child (most specific). This inverts the normal
271 Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If the
272 object is an instance of C<Report::IncomeAndExpenses> then this call is a
273 no-op, and just returns false. It's a good idea to always call C<inner()> to
274 allow for future subclassing.
276 =head1 OVERRIDE AND SUPER
278 Finally, Moose provides some simple sugar for Perl's built-in method
279 overriding scheme. If you want to override a method from a parent
280 class, you can do this with C<override>:
288 has 'job_title' => ( is => 'rw' );
290 override 'display_name' => sub {
293 return super() . q{, } . $self->title();
296 The call to C<super()> is almost the same as calling C<<
297 $self->SUPER::display_name >>. The difference is that the arguments
298 passed to the superclass's method will always be the same as the ones
299 passed to the method modifier, and cannot be changed.
301 All arguments passed to C<super()> are ignored, as are any changes
302 made to C<@_> before C<super()> is called.
306 Because all of these method modifiers are implemented as Perl
307 functions, you must always end the modifier declaration with a
310 after 'foo' => sub { };
316 These method modification features do not work well with multiple inheritance,
317 due to how method resolution is performed in Perl. Experiment with a test
318 program to ensure your class hierarchy works as expected, or more preferably,
319 don't use multiple inheritance (roles can help with this)!