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

Re^4: Monkey patching all subs with a basic 'starting subname' message

by Anonymous Monk
on Jul 17, 2017 at 20:11 UTC ( [id://1195273]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Monkey patching all subs with a basic 'starting subname' message
in thread Monkey patching all subs with a basic 'starting subname' message

> Not sure what this "meat" is supposed to mean (?)

In this case, meat == "majority". As in, what was...

*$_ = sub { __dbg { "Starting ${package}::${fname}(", join(',', @_), ')' } 4; my @ret = $fn->(@_); };

...now becomes...

*$_ = eval qq{sub $proto { __dbg { "Starting ${package}::${fname}(", join(',', \@_), ')' } 4; my \@ret = \$fn->(\@_); }};

The eval of an escaped+interpolated string is now just as worrying as the other stuff I was worried about!

All of which, I'm sure, is the least of my worries!

Replies are listed 'Best First'.
Re^5: Monkey patching all subs with a basic 'starting subname' message
by LanX (Saint) on Jul 17, 2017 at 20:18 UTC
    > The eval of an escaped+interpolated string is now just as worrying as the other stuff I was worried about!

    I'm sure there are better ways, for instance I'd try to use closure variables.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      I thought the first case was a closure variable. i.e.

      • Closure variable: my $foo = sub { ... };
      • Eval string: my $foo = eval qq{ sub { ... } };

      The thing is, I can only see how I might get the output of prototype into the string and not the closure. i.e.

      • Closure variable:
        my $original_proto = prototype("${package}::${sub_name}"); my $original_sub = \${"${package}::${sub_name}"}; *{"${package}::${sub_name}"} = sub HOW_DO_I_GET_$original_proto_IN_HER +E? { return $original_sub->(@_); };
      • Eval String:
        my $original_proto = prototype("${package}::${sub_name}"); my $original_sub = \${"${package}::${sub_name}"}; *{"${package}::${sub_name}"} = eval qq{sub $original_proto { return \$ +original_sub->(\@_); } };

      Am I missing something obvious?

        I just now noticed Sub::Metadata, which allows you to retrieve (and manipulate) the prototype (but not the signature) of a subroutine. Maybe that one could help you here.

        The module claims to work even with Perl 5.6, so most Perl versions should be supported.

        > sub HOW_DO_I_GET_$original_proto_IN_HERE? {

        AFAIK it's only possible via eval, if you think you've already delegated the maximum possible into closures, you should be fine.

        I'm sure if you dig long enough into CPAN you'll find some (semi-) official hack to change the prototype.

        YMMV.

        Good luck

        PS: Hope you're already aware of the trace options in perldebug

        frame Affects the printing of messages upon entry and exit from subroutines. + If frame & 2 is false, messages are printed on entry only. (Printing + on exit might be useful if interspersed with other messages.) If frame & 4 , arguments to functions are printed, plus context and ca +ller info. If frame & 8 , overloaded stringify and tied FETCH is enab +led on the printed arguments. If frame & 16 , the return value from t +he subroutine is printed. The length at which the argument list is truncated is governed by the +next option:

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-04-23 16:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found