9 no warnings 'redefine';
10 *CORE::GLOBAL::caller = sub (;$) {
11 my ($height) = ($_[0]||0);
15 my @caller = CORE::caller($i++) or return;
16 $caller[3] = $name_cache if $name_cache;
17 $name_cache = $caller[0] eq 'Hook::LexWrap' ? $caller[3] : '';
18 next if $name_cache || $height-- != 0;
19 return wantarray ? @_ ? @caller : @caller[0..2] : $caller[0];
24 sub import { no strict 'refs'; *{caller()."::wrap"} = \&wrap }
26 sub wrap (*@) { ## no critic Prototypes
27 my ($typeglob, %wrapper) = @_;
28 $typeglob = (ref $typeglob || $typeglob =~ /::/)
30 : caller()."::$typeglob";
34 $original = ref $typeglob eq 'CODE' && $typeglob
36 || croak "Can't wrap non-existent subroutine ", $typeglob;
38 croak "'$_' value is not a subroutine reference"
39 foreach grep {$wrapper{$_} && ref $wrapper{$_} ne 'CODE'}
41 no warnings 'redefine';
42 my ($caller, $unwrap) = *CORE::GLOBAL::caller{CODE};
44 if ($unwrap) { goto &$original }
45 my ($return, $prereturn);
47 $prereturn = $return = [];
48 () = $wrapper{pre}->(@_,$return) if $wrapper{pre};
49 if (ref $return eq 'ARRAY' && $return == $prereturn && !@$return) {
50 $return = [ &$original ];
51 () = $wrapper{post}->(@_, $return)
54 return ref $return eq 'ARRAY' ? @$return : ($return);
56 elsif (defined wantarray) {
57 $return = bless sub {$prereturn=1}, 'Hook::LexWrap::Cleanup';
58 my $dummy = $wrapper{pre}->(@_, $return) if $wrapper{pre};
61 $dummy = scalar $wrapper{post}->(@_, $return)
67 $return = bless sub {$prereturn=1}, 'Hook::LexWrap::Cleanup';
68 $wrapper{pre}->(@_, $return) if $wrapper{pre};
71 $wrapper{post}->(@_, $return)
77 ref $typeglob eq 'CODE' and return defined wantarray
79 : carp "Uselessly wrapped subroutine reference in void context";
82 *{$typeglob} = $imposter;
84 return unless defined wantarray;
85 return bless sub{ $unwrap=1 }, 'Hook::LexWrap::Cleanup';
88 package Hook::LexWrap::Cleanup;
90 sub DESTROY { $_[0]->() }
92 q{""} => sub { undef },
93 q{0+} => sub { undef },
94 q{bool} => sub { undef };
103 Hook::LexWrap - Lexically scoped subroutine wrappers
107 This document describes version 0.21 of Hook::LexWrap,
108 released November 6, 2008.
114 sub doit { print "[doit:", caller, "]"; return {my=>"data"} }
118 pre => sub { print "[pre1: @_]\n" },
119 post => sub { print "[post1:@_]\n"; $_[1]=9; };
121 my $temporarily = wrap doit,
122 post => sub { print "[post2:@_]\n" },
123 pre => sub { print "[pre2: @_]\n "};
126 doit(@args); # pre2->pre1->doit->post1->post2
130 doit(@args); # pre1->doit->post1
135 Hook::LexWrap allows you to install a pre- or post-wrapper (or both)
136 around an existing subroutine. Unlike other modules that provide this
137 capacity (e.g. Hook::PreAndPost and Hook::WrapSub), Hook::LexWrap
138 implements wrappers in such a way that the standard C<caller> function
139 works correctly within the wrapped subroutine.
141 To install a prewrappers, you write:
145 wrap 'subroutine_name', pre => \&some_other_sub;
147 #or: wrap *subroutine_name, pre => \&some_other_sub;
149 The first argument to C<wrap> is a string containing the name of the
150 subroutine to be wrapped (or the typeglob containing it, or a
151 reference to it). The subroutine name may be qualified, and the
152 subroutine must already be defined. The second argument indicates the
153 type of wrapper being applied and must be either C<'pre'> or
154 C<'post'>. The third argument must be a reference to a subroutine that
155 implements the wrapper.
157 To install a post-wrapper, you write:
159 wrap 'subroutine_name', post => \&yet_another_sub;
161 #or: wrap *subroutine_name, post => \&yet_another_sub;
163 To install both at once:
165 wrap 'subroutine_name',
166 pre => \&some_other_sub,
167 post => \&yet_another_sub;
171 wrap *subroutine_name,
172 post => \&yet_another_sub, # order in which wrappers are
173 pre => \&some_other_sub; # specified doesn't matter
175 Once they are installed, the pre- and post-wrappers will be called before
176 and after the subroutine itself, and will be passed the same argument list.
178 The pre- and post-wrappers and the original subroutine also all see the same
179 (correct!) values from C<caller> and C<wantarray>.
182 =head2 Short-circuiting and long-circuiting return values
184 The pre- and post-wrappers both receive an extra argument in their @_
185 arrays. That extra argument is appended to the original argument list
186 (i.e. is can always be accessed as $_[-1]) and acts as a place-holder for
187 the original subroutine's return value.
189 In a pre-wrapper, $_[-1] is -- for obvious reasons -- C<undef>. However,
190 $_[-1] may be assigned to in a pre-wrapper, in which case Hook::LexWrap
191 assumes that the original subroutine has been "pre-empted", and that
192 neither it, nor the corresponding post-wrapper, nor any wrappers that
193 were applied I<before> the pre-empting pre-wrapper was installed, need
194 be run. Note that any post-wrappers that were installed after the
195 pre-empting pre-wrapper was installed I<will> still be called before the
196 original subroutine call returns.
198 In a post-wrapper, $_[-1] contains the return value produced by the
199 wrapped subroutine. In a scalar return context, this value is the scalar
200 return value. In an list return context, this value is a reference to
201 the array of return values. $_[-1] may be assigned to in a post-wrapper,
202 and this changes the return value accordingly.
204 Access to the arguments and return value is useful for implementing
205 techniques such as memoization:
209 pre => sub { $_[-1] = $cache{$_[0]} if $cache{$_[0]} },
210 post => sub { $cache{$_[0]} = $_[-1] };
213 or for converting arguments and return values in a consistent manner:
215 # set_temp expects and returns degrees Fahrenheit,
216 # but we want to use Celsius
218 pre => sub { splice @_, 0, 1, $_[0] * 1.8 + 32 },
219 post => sub { $_[-1] = ($_[0] - 32) / 1.8 };
222 =head2 Lexically scoped wrappers
224 Normally, any wrappers installed by C<wrap> remain attached to the
225 subroutine until it is undefined. However, it is possible to make
226 specific wrappers lexically bound, so that they operate only until
227 the end of the scope in which they're created (or until some other
228 specific point in the code).
230 If C<wrap> is called in a I<non-void> context:
232 my $lexical = wrap 'sub_name', pre => \&wrapper;
234 it returns a special object corresponding to the particular wrapper being
235 placed around the original subroutine. When that object is destroyed
236 -- when its container variable goes out of scope, or when its
237 reference count otherwise falls to zero (e.g. C<undef $lexical>), or
238 when it is explicitly destroyed (C<$lexical-E<gt>DESTROY>) --
239 the corresponding wrapper is removed from around
240 the original subroutine. Note, however, that all other wrappers around the
241 subroutine are preserved.
244 =head2 Anonymous wrappers
246 If the subroutine to be wrapped is passed as a reference (rather than by name
247 or by typeglob), C<wrap> does not install the wrappers around the
248 original subroutine. Instead it generates a new subroutine which acts
249 as if it were the original with those wrappers around it.
250 It then returns a reference to that new subroutine. Only calls to the original
251 through that wrapped reference invoke the wrappers. Direct by-name calls to
252 the original, or calls through another reference, do not.
254 If the original is subsequently wrapped by name, the anonymously wrapped
255 subroutine reference does not see those wrappers. In other words,
256 wrappers installed via a subroutine reference are completely independent
257 of those installed via the subroutine's name (or typeglob).
261 sub original { print "ray" }
263 # Wrap anonymously...
264 my $anon_wrapped = wrap \&original, pre => sub { print "do..." };
267 original(); # prints "ray"
268 $anon_wrapped->(); # prints "do..ray"
272 pre => sub { print "fa.." },
273 post => sub { print "..mi" };
276 original(); # now prints "fa..ray..mi"
277 $anon_wrapped->(); # still prints "do...ray"
284 =item C<Can't wrap non-existent subroutine %s>
286 An attempt was made to wrap a subroutine that was not defined at the
289 =item C<'pre' value is not a subroutine reference>
291 The value passed to C<wrap> after the C<'pre'> flag was not
292 a subroutine reference. Typically, someone forgot the C<sub> on
293 the anonymous subroutine:
295 wrap 'subname', pre => { your_code_here() };
297 and Perl interpreted the last argument as a hash constructor.
299 =item C<'post' value is not a subroutine reference>
301 The value passed to C<wrap> after the C<'post'> flag was not
302 a subroutine reference.
304 =item C<Uselessly wrapped subroutine reference in void context> (warning only)
306 When the subroutine to be wrapped is passed as a subroutine reference,
307 C<wrap> does not install the wrapper around the original, but instead
308 returns a reference to a subroutine which wraps the original
309 (see L<Anonymous wrappers>).
311 However, there's no point in doing this if you don't catch the resulting
312 subroutine reference.
318 Damian Conway (damian@conway.org)
323 Schwern made me do this (by implying it wasn't possible ;-)
328 There are undoubtedly serious bugs lurking somewhere in code this funky :-)
330 Bug reports and other feedback are most welcome.
339 Copyright (c) 2001, Damian Conway. All Rights Reserved.
340 This module is free software. It may be used, redistributed
341 and/or modified under the same terms as Perl itself.