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


In reply to Re: Altering subroutine parameters using Hook::LexWrap by Zaxo
in thread Altering subroutine parameters using Hook::LexWrap by Thilosophy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.