X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FMethodModifiers.pod;h=a264155081eb63a1a79f07d301d0993ed905f7e9;hb=2349e3cb4319b549f00a9303dc408be332bf9f7f;hp=3325dabd18dab736abd8559e58097675df74336e;hpb=6549b0d1ae8b084898ac2d8ad60d6a57cccf4124;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/MethodModifiers.pod b/lib/Moose/Manual/MethodModifiers.pod index 3325dab..a264155 100644 --- a/lib/Moose/Manual/MethodModifiers.pod +++ b/lib/Moose/Manual/MethodModifiers.pod @@ -1,8 +1,10 @@ -=pod +package Moose::Manual::MethodModifiers; + +# ABSTRACT: Moose's method modifiers -=head1 NAME +__END__ -Moose::Manual::MethodModifiers - Moose's method modifiers +=pod =head1 WHAT IS A METHOD MODIFIER? @@ -16,7 +18,7 @@ It's probably easiest to understand this feature with a few examples: use Moose; sub foo { - print "foo\n"; + print " foo\n"; } before 'foo' => sub { print "about to call foo\n"; }; @@ -26,19 +28,19 @@ It's probably easiest to understand this feature with a few examples: my $orig = shift; my $self = shift; - print "I'm around foo\n"; + print " I'm around foo\n"; $self->$orig(@_); - print "I'm still around foo\n"; + print " I'm still around foo\n"; }; Now if I call C<< Example->new->foo >> I'll get the following output: about to call foo - I'm around foo - foo - I'm still around foo + I'm around foo + foo + I'm still around foo just called foo You probably could have figured that out from the names "before", @@ -63,18 +65,22 @@ modifiers run from first added to last: =head1 WHY USE THEM? -Method modifiers have many uses. One very common use is in roles. This -lets roles alter the behavior of methods in the classes that use -them. See L for more information about roles. +Method modifiers have many uses. They are often used in roles to alter the +behavior of methods in the classes that consume the role. See +L for more information about roles. -Most of the modifiers are most useful in roles, so some of the -examples below are a bit artificial. They're intended to give you an -idea of how modifiers work, but may not be the most natural usage. +Since modifiers are mostly useful in roles, some of the examples below +are a bit artificial. They're intended to give you an idea of how +modifiers work, but may not be the most natural usage. =head1 BEFORE, AFTER, AND AROUND -Method modifiers can also be used to add behavior to a method that -Moose generates for you, such as an attribute accessor: +Method modifiers can be used to add behavior to methods without modifying the definition of those methods. + +=head2 BEFORE and AFTER modifiers + +Method modifiers can be used to add behavior to a method that Moose +generates for you, such as an attribute accessor: has 'size' => ( is => 'rw' ); @@ -106,11 +112,13 @@ was taken. Note that the return values of both before and after modifiers are ignored. -An around modifier is a bit more powerful than either a before or +=head2 AROUND modifiers + +An around modifier is more powerful than either a before or after modifier. It can modify the arguments being passed to the original method, and you can even decide to simply not call the -original method at all. Finally, you can modify the return value with -an around modifier. +original method at all. You can also modify the return value with an +around modifier. An around modifier receives the original method as its first argument, I the object, and finally any arguments passed to the method. @@ -129,6 +137,50 @@ I the object, and finally any arguments passed to the method. return $self->$orig($size); }; +=head2 Wrapping multiple methods at once + +C, C, and C can also modify multiple methods +at once. The simplest example of this is passing them as a list: + + before [qw(foo bar baz)] => sub { + warn "something is being called!"; + }; + +This will add a C modifier to each of the C, C, +and C methods in the current class, just as though a separate +call to C was made for each of them. The list can be passed +either as a bare list, or as an arrayref. Note that the name of the +function being modified isn't passed in in any way; this syntax is +only intended for cases where the function being modified doesn't +actually matter. If the function name does matter, use something like this: + + for my $func (qw(foo bar baz)) { + before $func => sub { + warn "$func was called!"; + }; + } + +=head2 Using regular expressions to select methods to wrap + +In addition, you can specify a regular expression to indicate the +methods to wrap, like so: + + after qr/^command_/ => sub { + warn "got a command"; + }; + +This will match the regular expression against each method name +returned by L, and add a modifier +to each one that matches. The same caveats apply as above. + +Using regular expressions to determine methods to wrap is quite a bit more +powerful than the previous alternatives, but it's also quite a bit more +dangerous. Bear in mind that if your regular expression matches certain Perl +and Moose reserved method names with a special meaning to Moose or Perl, such +as C, C, C, C, C, etc, this could cause +unintended (and hard to debug) problems and is best avoided. + + =head1 INNER AND AUGMENT Augment and inner are two halves of the same feature. The augment @@ -166,9 +218,9 @@ implementation: augment 'as_xml' => sub { my $self = shift; - my $xml = "\n"; + my $xml = " \n"; $xml .= inner(); - $xml .= "\n"; + $xml .= " \n"; return $xml; }; @@ -176,8 +228,8 @@ implementation: When we call C on a Report object, we get something like this: - - + + But we also called C in C, so we can continue @@ -192,9 +244,9 @@ subclassing and adding more content inside the document: augment 'as_xml' => sub { my $self = shift; - my $xml = '' . $self->income . ''; + my $xml = ' ' . $self->income . ''; $xml .= "\n"; - my $xml = '' . $self->expenses . ''; + $xml .= ' ' . $self->expenses . ''; $xml .= "\n"; $xml .= inner() || q{}; @@ -205,10 +257,10 @@ subclassing and adding more content inside the document: Now our report has some content: - - $10 - $8 - + + $10 + $8 + What makes this combination of C and C special is @@ -216,9 +268,10 @@ that it allows us to have methods which are called from parent (least specific) to child (most specific). This inverts the normal inheritance pattern. -Note that in C we call C again. If -the object is an instance of C then this -call is a no-op, and just returns false. +Note that in C we call C again. If the +object is an instance of C then this call is a +no-op, and just returns false. It's a good idea to always call C to +allow for future subclassing. =head1 OVERRIDE AND SUPER @@ -256,17 +309,13 @@ semi-colon: after 'foo' => sub { }; -=head1 AUTHOR - -Dave Rolsky Eautarch@urth.orgE - -=head1 COPYRIGHT AND LICENSE +=cut -Copyright 2008-2009 by Infinity Interactive, Inc. +=head1 CAVEATS -L +These method modification features do not work well with multiple inheritance, +due to how method resolution is performed in Perl. Experiment with a test +program to ensure your class hierarchy works as expected, or more preferably, +don't use multiple inheritance (roles can help with this)! -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. -=cut