Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Altering subroutine parameters using Hook::LexWrap

by Zaxo (Archbishop)
on Jan 19, 2005 at 04:09 UTC ( [id://423266]=note: print w/replies, xml ) Need Help??


in reply to Altering subroutine parameters using Hook::LexWrap

By altering $_[-1] in before(), you've instructed the pre-wrap to short-circuit and not call the wrapped sub at all.

Access to wrappers is fairly easy, you just need to keep a lexical copy of the wrap call's returned object. You can kill a particular wrapper by undefining that object or letting it go out of scope.

Changing @_ directly with unshift, shift, push pop or splice in a pre- routine doesn't work. It confuses Hook::LexWrap and doesn't confer aliasing to any added variables. If you want to change an argument, work on individual elements of @_. The only way I've found to change the number of arguments is to design the wrapped sub to take a reference to a data structure and work on that.

Here's an example from my scratchpad of using Hook::LexWrap,

#!/usr/bin/perl use strict; use warnings; use Hook::LexWrap; { my $foo; sub foo { @_ ? $foo = shift : $foo; } # _not_ an lvalue! my $wrapper = wrap *foo, pre => sub { warn 0+@_, " @_"; $_[0] = lc $_[0] if @_ > 1; warn 0+@_, " @_"; }, post => sub { $_[-1] = wantarray ? [ map {uc} @{$_[-1]} ] : uc $_[-1] }; sub wrapper () :lvalue { $wrapper } # keeps the cloistered # lexwrap alive sub _foo () :lvalue { $foo } # inspection hatch } my $str = 'Quux'; my $tmp = $str; printf "Given $str, wrapped setter reports %s, backdoor shows %s, arg +is now %s.\n", foo($tmp), _foo, $tmp; # setter printf "Wrapped getter reports %s, and backdoor shows %s\n", foo(), _foo; # getter __END__ 2 Quux ARRAY(0x804b3f8) at hlw.pl line 13. 2 quux ARRAY(0x804b3f8) at hlw.pl line 15. Given Quux, wrapped setter reports QUUX, backdoor shows Quux, arg is n +ow Quux. 1 ARRAY(0x804b50c) at hlw.pl line 13. 1 ARRAY(0x804b50c) at hlw.pl line 15. Wrapped getter reports QUUX, and backdoor shows Quux

You can keep a clean copy of some_sub() around by wrapping a hard reference to it instead of a name-or-glob. Wrap then returns a reference to a newly constructed sub with wrappers, and the original is unmodified. The pre- wrapper would then be free to call the original if you liked, having short-circuited the wrapping mechanism.

You may note the "not an lvalue!" comment. Hook::LexWrap does not set the original's attributes for the wrapped version.

After Compline,
Zaxo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://423266]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-20 01:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found