1Class::Method::ModifierUss(e3r)Contributed Perl DocumentCaltaisosn::Method::Modifiers(3)
2
3
4

NAME

6       Class::Method::Modifiers - Provides Moose-like method modifiers
7

VERSION

9       version 2.13
10

SYNOPSIS

12           package Child;
13           use parent 'MyParent';
14           use Class::Method::Modifiers;
15
16           sub new_method { }
17
18           before 'old_method' => sub {
19               carp "old_method is deprecated, use new_method";
20           };
21
22           around 'other_method' => sub {
23               my $orig = shift;
24               my $ret = $orig->(@_);
25               return $ret =~ /\d/ ? $ret : lc $ret;
26           };
27
28           after 'private', 'protected' => sub {
29               debug "finished calling a dangerous method";
30           };
31
32           use Class::Method::Modifiers qw(fresh);
33
34           fresh 'not_in_hierarchy' => sub {
35               warn "freshly added method\n";
36           };
37

DESCRIPTION

39       Method modifiers are a convenient feature from the CLOS (Common Lisp
40       Object System) world.
41
42       In its most basic form, a method modifier is just a method that calls
43       "$self->SUPER::foo(@_)". I for one have trouble remembering that exact
44       invocation, so my classes seldom re-dispatch to their base classes.
45       Very bad!
46
47       "Class::Method::Modifiers" provides three modifiers: "before",
48       "around", and "after". "before" and "after" are run just before and
49       after the method they modify, but can not really affect that original
50       method. "around" is run in place of the original method, with a hook to
51       easily call that original method.  See the "MODIFIERS" section for more
52       details on how the particular modifiers work.
53
54       One clear benefit of using "Class::Method::Modifiers" is that you can
55       define multiple modifiers in a single namespace. These separate
56       modifiers don't need to know about each other. This makes top-down
57       design easy. Have a base class that provides the skeleton methods of
58       each operation, and have plugins modify those methods to flesh out the
59       specifics.
60
61       Parent classes need not know about "Class::Method::Modifiers". This
62       means you should be able to modify methods in any subclass. See
63       Term::VT102::ZeroBased for an example of subclassing with
64       "Class::Method::Modifiers".
65
66       In short, "Class::Method::Modifiers" solves the problem of making sure
67       you call "$self->SUPER::foo(@_)", and provides a cleaner interface for
68       it.
69
70       As of version 1.00, "Class::Method::Modifiers" is faster in some cases
71       than Moose. See benchmark/method_modifiers.pl in the Moose
72       distribution.
73
74       "Class::Method::Modifiers" also provides an additional "modifier" type,
75       "fresh"; see below.
76

MODIFIERS

78       All modifiers let you modify one or multiple methods at a time. The
79       names of multiple methods can be provided as a list or as an array-
80       reference. Examples:
81
82        before 'method' => sub { ... };
83        before 'method1', 'method2' => sub { ... };
84        before [ 'method1', 'method2' ] => sub { ... };
85
86   before method(s) => sub { ... };
87       "before" is called before the method it is modifying. Its return value
88       is totally ignored. It receives the same @_ as the method it is
89       modifying would have received. You can modify the @_ the original
90       method will receive by changing $_[0] and friends (or by changing
91       anything inside a reference).  This is a feature!
92
93   after method(s) => sub { ... };
94       "after" is called after the method it is modifying. Its return value is
95       totally ignored. It receives the same @_ as the method it is modifying
96       received, mostly. The original method can modify @_ (such as by
97       changing $_[0] or references) and "after" will see the modified
98       version. If you don't like this behavior, specify both a "before" and
99       "after", and copy the @_ during "before" for "after" to use.
100
101   around method(s) => sub { ... };
102       "around" is called instead of the method it is modifying. The method
103       you're overriding is passed in as the first argument (called $orig by
104       convention).  Watch out for contextual return values of $orig.
105
106       You can use "around" to:
107
108       Pass $orig a different @_
109               around 'method' => sub {
110                   my $orig = shift;
111                   my $self = shift;
112                   $orig->($self, reverse @_);
113               };
114
115       Munge the return value of $orig
116               around 'method' => sub {
117                   my $orig = shift;
118                   ucfirst $orig->(@_);
119               };
120
121       Avoid calling $orig -- conditionally
122               around 'method' => sub {
123                   my $orig = shift;
124                   return $orig->(@_) if time() % 2;
125                   return "no dice, captain";
126               };
127
128   fresh method(s) => sub { ... };
129       (Available since version 2.00)
130
131       Unlike the other modifiers, this does not modify an existing method.
132       Ordinarily, "fresh" merely installs the coderef as a method in the
133       appropriate class; but if the class hierarchy already contains a method
134       of the same name, an exception is thrown.  The idea of this "modifier"
135       is to increase safety when subclassing.  Suppose you're writing a
136       subclass of a class Some::Base, and adding a new method:
137
138           package My::Subclass;
139           use base 'Some::Base';
140
141           sub foo { ... }
142
143       If a later version of Some::Base also adds a new method named "foo",
144       your method will shadow that method.  Alternatively, you can use
145       "fresh" to install the additional method into your subclass:
146
147           package My::Subclass;
148           use base 'Some::Base';
149
150           use Class::Method::Modifiers 'fresh';
151
152           fresh 'foo' => sub { ... };
153
154       Now upgrading Some::Base to a version with a conflicting "foo" method
155       will cause an exception to be thrown; seeing that error will give you
156       the opportunity to fix the problem (perhaps by picking a different
157       method name in your subclass, or similar).
158
159       Creating fresh methods with "install_modifier" (see below) provides a
160       way to get similar safety benefits when adding local monkeypatches to
161       existing classes; see
162       <http://aaroncrane.co.uk/talks/monkey_patching_subclassing/>.
163
164       For API compatibility reasons, this function is exported only when you
165       ask for it specifically, or for ":all".
166
167   install_modifier $package, $type, @names, sub { ... }
168       "install_modifier" is like "before", "after", "around", and "fresh" but
169       it also lets you dynamically select the modifier type ('before',
170       'after', 'around', 'fresh') and package that the method modifiers are
171       installed into. This expert-level function is exported only when you
172       ask for it specifically, or for ":all".
173

NOTES

175       All three normal modifiers; "before", "after", and "around"; are
176       exported into your namespace by default. You may "use
177       Class::Method::Modifiers ()" to avoid modifying your namespace. I may
178       steal more features from Moose, namely "super", "override", "inner",
179       "augment", and whatever the Moose folks come up with next.
180
181       Note that the syntax and semantics for these modifiers is directly
182       borrowed from Moose (the implementations, however, are not).
183
184       Class::Trigger shares a few similarities with
185       "Class::Method::Modifiers", and they even have some overlap in purpose
186       -- both can be used to implement highly pluggable applications. The
187       difference is that Class::Trigger provides a mechanism for easily
188       letting parent classes to invoke hooks defined by other code.
189       "Class::Method::Modifiers" provides a way of overriding/augmenting
190       methods safely, and the parent class need not know about it.
191
192   :lvalue METHODS
193       When adding "before" or "after" modifiers, the wrapper method will be
194       an lvalue method if the wrapped sub is, and assigning to the method
195       will propagate to the wrapped method as expected.  For "around"
196       modifiers, it is the modifier sub that determines if the wrapper method
197       is an lvalue method.
198

CAVEATS

200       It is erroneous to modify a method that doesn't exist in your class's
201       inheritance hierarchy. If this occurs, an exception will be thrown when
202       the modifier is defined.
203
204       It doesn't yet play well with "caller". There are some "TODO" tests for
205       this.  Don't get your hopes up though!
206
207       Applying modifiers to array lvalue methods is not fully supported.
208       Attempting to assign to an array lvalue method that has an "after"
209       modifier applied will result in an error.  Array lvalue methods are not
210       well supported by perl in general, and should be avoided.
211

MAJOR VERSION CHANGES

213       This module was bumped to 1.00 following a complete reimplementation,
214       to indicate breaking backwards compatibility. The "guard" modifier was
215       removed, and the internals are completely different.
216
217       The new version is a few times faster with half the code. It's now even
218       faster than Moose.
219
220       Any code that just used modifiers should not change in behavior, except
221       to become more correct. And, of course, faster. :)
222

SEE ALSO

224       •   Class::Method::Modifiers::Fast
225
226       •   Moose
227
228       •   Class::Trigger
229
230       •   Class::MOP::Method::Wrapped
231
232       •   MRO::Compat
233
234       •   CLOS <https://en.wikipedia.org/wiki/Common_Lisp_Object_System>
235

ACKNOWLEDGEMENTS

237       Thanks to Stevan Little for Moose, I would never have known about
238       method modifiers otherwise.
239
240       Thanks to Matt Trout and Stevan Little for their advice.
241

SUPPORT

243       Bugs may be submitted through the RT bug tracker
244       <https://rt.cpan.org/Public/Dist/Display.html?Name=Class-Method-
245       Modifiers> (or bug-Class-Method-Modifiers@rt.cpan.org <mailto:bug-
246       Class-Method-Modifiers@rt.cpan.org>).
247

AUTHOR

249       Shawn M Moore <sartak@gmail.com>
250

CONTRIBUTORS

252       •   Karen Etheridge <ether@cpan.org>
253
254       •   Shawn M Moore <code@sartak.org>
255
256       •   Graham Knop <haarg@haarg.org>
257
258       •   Aaron Crane <arc@cpan.org>
259
260       •   Peter Rabbitson <ribasushi@cpan.org>
261
262       •   Justin Hunter <justin.d.hunter@gmail.com>
263
264       •   David Steinbrunner <dsteinbrunner@pobox.com>
265
266       •   gfx <gfuji@cpan.org>
267
268       •   mannih <github@lxxi.org>
269
271       This software is copyright (c) 2007 by Shawn M Moore.
272
273       This is free software; you can redistribute it and/or modify it under
274       the same terms as the Perl 5 programming language system itself.
275
276
277
278perl v5.34.0                      2022-01-21       Class::Method::Modifiers(3)
Impressum