1Hook::LexWrap(3)      User Contributed Perl Documentation     Hook::LexWrap(3)
2
3
4

NAME

6       Hook::LexWrap - Lexically scoped subroutine wrappers
7

VERSION

9       This document describes version 0.21 of Hook::LexWrap, released
10       November  6, 2008.
11

SYNOPSIS

13               use Hook::LexWrap;
14
15               sub doit { print "[doit:", caller, "]"; return {my=>"data"} }
16
17               SCOPED: {
18                       wrap doit,
19                               pre  => sub { print "[pre1: @_]\n" },
20                               post => sub { print "[post1:@_]\n"; $_[1]=9; };
21
22                       my $temporarily = wrap doit,
23                               post => sub { print "[post2:@_]\n" },
24                               pre  => sub { print "[pre2: @_]\n  "};
25
26                       @args = (1,2,3);
27                       doit(@args);    # pre2->pre1->doit->post1->post2
28               }
29
30               @args = (4,5,6);
31               doit(@args);            # pre1->doit->post1
32

DESCRIPTION

34       Hook::LexWrap allows you to install a pre- or post-wrapper (or both)
35       around an existing subroutine. Unlike other modules that provide this
36       capacity (e.g. Hook::PreAndPost and Hook::WrapSub), Hook::LexWrap
37       implements wrappers in such a way that the standard "caller" function
38       works correctly within the wrapped subroutine.
39
40       To install a prewrappers, you write:
41
42               use Hook::LexWrap;
43
44               wrap 'subroutine_name', pre => \&some_other_sub;
45
46          #or: wrap *subroutine_name,  pre => \&some_other_sub;
47
48       The first argument to "wrap" is a string containing the name of the
49       subroutine to be wrapped (or the typeglob containing it, or a reference
50       to it). The subroutine name may be qualified, and the subroutine must
51       already be defined. The second argument indicates the type of wrapper
52       being applied and must be either 'pre' or 'post'. The third argument
53       must be a reference to a subroutine that implements the wrapper.
54
55       To install a post-wrapper, you write:
56
57               wrap 'subroutine_name', post => \&yet_another_sub;
58
59          #or: wrap *subroutine_name,  post => \&yet_another_sub;
60
61       To install both at once:
62
63               wrap 'subroutine_name',
64                    pre  => \&some_other_sub,
65                    post => \&yet_another_sub;
66
67       or:
68
69               wrap *subroutine_name,
70                    post => \&yet_another_sub,  # order in which wrappers are
71                    pre  => \&some_other_sub;   # specified doesn't matter
72
73       Once they are installed, the pre- and post-wrappers will be called
74       before and after the subroutine itself, and will be passed the same
75       argument list.
76
77       The pre- and post-wrappers and the original subroutine also all see the
78       same (correct!) values from "caller" and "wantarray".
79
80   Short-circuiting and long-circuiting return values
81       The pre- and post-wrappers both receive an extra argument in their @_
82       arrays. That extra argument is appended to the original argument list
83       (i.e. is can always be accessed as $_[-1]) and acts as a place-holder
84       for the original subroutine's return value.
85
86       In a pre-wrapper, $_[-1] is -- for obvious reasons -- "undef". However,
87       $_[-1] may be assigned to in a pre-wrapper, in which case Hook::LexWrap
88       assumes that the original subroutine has been "pre-empted", and that
89       neither it, nor the corresponding post-wrapper, nor any wrappers that
90       were applied before the pre-empting pre-wrapper was installed, need be
91       run. Note that any post-wrappers that were installed after the pre-
92       empting pre-wrapper was installed will still be called before the
93       original subroutine call returns.
94
95       In a post-wrapper, $_[-1] contains the return value produced by the
96       wrapped subroutine. In a scalar return context, this value is the
97       scalar return value. In an list return context, this value is a
98       reference to the array of return values. $_[-1] may be assigned to in a
99       post-wrapper, and this changes the return value accordingly.
100
101       Access to the arguments and return value is useful for implementing
102       techniques such as memoization:
103
104               my %cache;
105               wrap fibonacci,
106                       pre  => sub { $_[-1] = $cache{$_[0]} if $cache{$_[0]} },
107                       post => sub { $cache{$_[0]} = $_[-1] };
108
109       or for converting arguments and return values in a consistent manner:
110
111               # set_temp expects and returns degrees Fahrenheit,
112               # but we want to use Celsius
113               wrap set_temp,
114                       pre   => sub { splice @_, 0, 1, $_[0] * 1.8 + 32 },
115                       post  => sub { $_[-1] = ($_[0] - 32) / 1.8 };
116
117   Lexically scoped wrappers
118       Normally, any wrappers installed by "wrap" remain attached to the
119       subroutine until it is undefined. However, it is possible to make
120       specific wrappers lexically bound, so that they operate only until the
121       end of the scope in which they're created (or until some other specific
122       point in the code).
123
124       If "wrap" is called in a non-void context:
125
126               my $lexical = wrap 'sub_name', pre => \&wrapper;
127
128       it returns a special object corresponding to the particular wrapper
129       being placed around the original subroutine. When that object is
130       destroyed -- when its container variable goes out of scope, or when its
131       reference count otherwise falls to zero (e.g. "undef $lexical"), or
132       when it is explicitly destroyed ("$lexical->DESTROY") -- the
133       corresponding wrapper is removed from around the original subroutine.
134       Note, however, that all other wrappers around the subroutine are
135       preserved.
136
137   Anonymous wrappers
138       If the subroutine to be wrapped is passed as a reference (rather than
139       by name or by typeglob), "wrap" does not install the wrappers around
140       the original subroutine. Instead it generates a new subroutine which
141       acts as if it were the original with those wrappers around it.  It then
142       returns a reference to that new subroutine. Only calls to the original
143       through that wrapped reference invoke the wrappers. Direct by-name
144       calls to the original, or calls through another reference, do not.
145
146       If the original is subsequently wrapped by name, the anonymously
147       wrapped subroutine reference does not see those wrappers. In other
148       words, wrappers installed via a subroutine reference are completely
149       independent of those installed via the subroutine's name (or typeglob).
150
151       For example:
152
153               sub original { print "ray" }
154
155               # Wrap anonymously...
156               my $anon_wrapped = wrap \&original, pre => sub { print "do..." };
157
158               # Show effects...
159               original();             # prints "ray"
160               $anon_wrapped->();      # prints "do..ray"
161
162               # Wrap nonymously...
163               wrap *original,
164                       pre  => sub { print "fa.." },
165                       post => sub { print "..mi" };
166
167               # Show effects...
168               original();             #   now prints "fa..ray..mi"
169               $anon_wrapped->();      # still prints "do...ray"
170

DIAGNOSTICS

172       "Can't wrap non-existent subroutine %s"
173           An attempt was made to wrap a subroutine that was not defined at
174           the point of wrapping.
175
176       "'pre' value is not a subroutine reference"
177           The value passed to "wrap" after the 'pre' flag was not a
178           subroutine reference. Typically, someone forgot the "sub" on the
179           anonymous subroutine:
180
181                   wrap 'subname', pre => { your_code_here() };
182
183           and Perl interpreted the last argument as a hash constructor.
184
185       "'post' value is not a subroutine reference"
186           The value passed to "wrap" after the 'post' flag was not a
187           subroutine reference.
188
189       "Uselessly wrapped subroutine reference in void context" (warning only)
190           When the subroutine to be wrapped is passed as a subroutine
191           reference, "wrap" does not install the wrapper around the original,
192           but instead returns a reference to a subroutine which wraps the
193           original (see "Anonymous wrappers").
194
195           However, there's no point in doing this if you don't catch the
196           resulting subroutine reference.
197

AUTHOR

199       Damian Conway (damian@conway.org)
200

BLAME

202       Schwern made me do this (by implying it wasn't possible ;-)
203

BUGS

205       There are undoubtedly serious bugs lurking somewhere in code this funky
206       :-)
207
208       Bug reports and other feedback are most welcome.
209

SEE ALSO

211       Sub::Prepend
212
214             Copyright (c) 2001, Damian Conway. All Rights Reserved.
215           This module is free software. It may be used, redistributed
216               and/or modified under the same terms as Perl itself.
217
218
219
220perl v5.12.0                      2008-12-18                  Hook::LexWrap(3)
Impressum