.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Hook::WrapSub 3pm" .TH Hook::WrapSub 3pm "2009-12-09" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Hook::WrapSub \- wrap subs with pre\- and post\-call hooks .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Hook::WrapSub qw( wrap_subs unwrap_subs ); \& \& wrap_subs \e&before, \*(Aqsome_func\*(Aq, \*(Aqanother_func\*(Aq, \e&after; \& \& unwrap_subs \*(Aqsome_func\*(Aq; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "wrap_subs" .IX Subsection "wrap_subs" This function enables intercepting a call to any named function; handlers may be added both before and after the call to the intercepted function. .PP For example: .PP .Vb 1 \& wrap_subs \e&before, \*(Aqsome_func\*(Aq, \e&after; .Ve .PP In this case, whenever the sub named 'some_func' is called, the &before sub is called first, and the &after sub is called afterwards. These are both optional. If you only want to intercept the call beforehand: .PP .Vb 1 \& wrap_subs \e&before, \*(Aqsome_func\*(Aq; .Ve .PP You may pass more than one sub name: .PP .Vb 1 \& wrap_subs \e&before, \*(Aqfoo\*(Aq, \*(Aqbar\*(Aq, \*(Aqbaz\*(Aq, \e&after; .Ve .PP and each one will have the same hooks applied. .PP The sub names may be qualified. Any unqualified names are assumed to reside in the package of the caller. .PP The &before sub and the &after sub are both passed the argument list which is destined for the wrapped sub. This can be inspected, and even altered, in the &before sub: .PP .Vb 6 \& sub before { \& ref($_[1]) && $_[1] =~ /\ebARRAY\eb/ \& or croak "2nd arg must be an array\-ref!"; \& @_ or @_ = qw( default values ); \& # if no args passed, insert some default values \& } .Ve .PP The &after sub is also passed this list. Modifications to it will (obviously) not be seen by the wrapped sub, but the caller will see the changes, if it happens to be looking. .PP Here's an example that causes a certain method call to be redirected to a specific object. (Note, we use splice to change \f(CW$_\fR[0], because assigning directly to \f(CW$_\fR[0] would cause the change to be visible to the caller, due to the magical aliasing nature of \f(CW@_\fR.) .PP .Vb 1 \& my $handler_object = new MyClass; \& \& Hook::WrapSub::wrap_subs \& sub { splice @_, 0, 1, $handler_object }, \& \*(AqMyClass::some_method\*(Aq; \& \& my $other_object = new MyClass; \& $other_object\->some_method; \& \& # even though the method is invoked on \& # $other_object, it will actually be executed \& # with a 0\*(Aqth argument = $handler_obj, \& # as arranged by the pre\-call hook sub. .Ve .SS "Package Variables" .IX Subsection "Package Variables" There are some Hook::WrapSub package variables defined, which the &before and &after subs may inspect. .ie n .IP "$Hook::WrapSub::name" 4 .el .IP "\f(CW$Hook::WrapSub::name\fR" 4 .IX Item "$Hook::WrapSub::name" This is the fully qualified name of the wrapped sub. .ie n .IP "@Hook::WrapSub::caller" 4 .el .IP "\f(CW@Hook::WrapSub::caller\fR" 4 .IX Item "@Hook::WrapSub::caller" This is a list which strongly resembles the result of a call to the built-in function \f(CW\*(C`caller\*(C'\fR; it is provided because calling \f(CW\*(C`caller\*(C'\fR will in fact produce confusing results; if your sub is inclined to call \f(CW\*(C`caller\*(C'\fR, have it look at this variable instead. .ie n .IP "@Hook::WrapSub::result" 4 .el .IP "\f(CW@Hook::WrapSub::result\fR" 4 .IX Item "@Hook::WrapSub::result" This contains the result of the call to the wrapped sub. It is empty in the &before sub. In the &after sub, it will be empty if the sub was called in a void context, it will contain one value if the sub was called in a scalar context; otherwise, it may have any number of elements. Note that the &after function is not prevented from modifying the contents of this array; any such modifications will be seen by the caller! .PP This simple example shows how Hook::WrapSub can be used to log certain subroutine calls: .PP .Vb 6 \& sub before { \& print STDERR <<" EOF"; \& About to call $Hook::WrapSub::name( @_ ); \& Wantarray=$Hook::WrapSub::caller[5] \& EOF \& } \& \& sub after { \& print STDERR <<" EOF"; \& Called $Hook::WrapSub::name( @_ ); \& Result=( @Hook::WrapSub::result ) \& EOF \& @Hook::WrapSub::result \& or @Hook::WrapSub::result = qw( default return ); \& # if the sub failed to return something... \& } .Ve .PP Much more elaborate uses are possible. Here's one one way it could be used with database operations: .PP .Vb 1 \& my $dbh; # initialized elsewhere. \& \& wrap_subs \& sub { \& $dbh\->checkpoint \& }, \& \& \*(AqMyDb::update\*(Aq, \& \*(AqMyDb::delete\*(Aq, \& \& sub { \& # examine result of sub call: \& if ( $Hook::WrapSub::result[0] ) { \& # success \& $dbh\->commit; \& } \& else { \& # failure \& $dbh\->rollback; \& } \& }; .Ve .SS "unwrap_subs" .IX Subsection "unwrap_subs" This removes the most recent wrapping of the named subs. .PP \&\s-1NOTE:\s0 Any given sub may be wrapped an unlimited number of times. A \*(L"stack\*(R" of the wrappings is maintained internally. wrap_subs \*(L"pushes\*(R" a wrapping, and unwrap_subs \*(L"pops\*(R". .SH "AUTHOR" .IX Header "AUTHOR" jdporter@min.net (John Porter) .SH "COPYRIGHT" .IX Header "COPYRIGHT" This is free software. This software may be modified and/or distributed under the same terms as Perl itself.