X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FMethodModifiers.pod;h=b982b0b6a02bc7c59ec74c1c55af0b3b80454bdf;hb=b1fffd0f881c6bec7bad398d38dbac35c98f4f3c;hp=875c6dbaf40f2dd80634c7bfc61222214917acc7;hpb=ce5e6e3cee4c37c44e1ccb88059b66ca02ff0525;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/MethodModifiers.pod b/lib/Moose/Manual/MethodModifiers.pod index 875c6db..b982b0b 100644 --- a/lib/Moose/Manual/MethodModifiers.pod +++ b/lib/Moose/Manual/MethodModifiers.pod @@ -1,13 +1,15 @@ -=pod +package Moose::Manual::MethodModifiers; + +# ABSTRACT: Moose's method modifiers -=head1 NAME +__END__ -Moose::Manual::Attribute - Moose's Method Modifiers +=pod =head1 WHAT IS A METHOD MODIFIER? -Moose provides a feature called "method modifiers". Another word for -this feature might be "hooks" or "advice". +Moose provides a feature called "method modifiers". You can also think +of these as "hooks" or "advice". It's probably easiest to understand this feature with a few examples: @@ -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,18 @@ 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 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. -Modifiers really are at their 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 usages. +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 a method that Moose +generates for you, such as an attribute accessor: has 'size' => ( is => 'rw' ); @@ -87,7 +89,7 @@ Moose generates for you, such as an attribute accessor: }; Another use for the before modifier would be to do some sort of -pre-checking on a method call. For example: +prechecking on a method call. For example: before 'size' => sub { my $self = shift; @@ -96,8 +98,9 @@ pre-checking on a method call. For example: if @_ && $self->is_growing; }; -This lets us implement logical checks that don't fit well into -constraints. +This lets us implement logical checks that don't make sense as type +constraints. In particular, they're useful for defining logical rules +about an object's state changes. Similarly, an after modifier could be used for logging an action that was taken. @@ -105,12 +108,11 @@ 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 -after modifier. First, it is easy to modify the arguments being passed -onto the original method in an around modifier. Second, you can decide -to simply not call the original method at all, unlike with other -modifiers. Finally, you can modify the return value with an around -modifier. +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. 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 +131,44 @@ I the object, and finally any arguments passed to the method. return $self->$orig($size); }; +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!"; + }; + } + +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. In particular, you should make sure to avoid wrapping +methods with a special meaning to Moose or Perl, such as C, C, +C, C, C, etc., as this could cause +unintended (and hard to debug) problems. + =head1 INNER AND AUGMENT Augment and inner are two halves of the same feature. The augment @@ -166,9 +206,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 +216,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 +232,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,21 +245,21 @@ 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 that it allows us to have methods which are called from parent (least -specific) to child (most specific). This inverts the normal order, -where the child's method is called first, and it in turn will call C<< -$self->SUPER::method >> to call the parent. +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 @@ -257,17 +297,4 @@ semi-colon: after 'foo' => sub { }; -=head1 AUTHOR - -Dave Rolsky Eautarch@urth.orgE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2008 by Infinity Interactive, Inc. - -L - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. - =cut