Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

While working on an existing Perl package file, I would like to log the start/end of each method call (preferably without adding any new dependencies to the module). I've already added a rudimentary __dbg sub, which I'm fond of, like so...

our $DEBUG_LEVEL = 5; sub __dbg (&;$) { my ($code, $verbosity) = @_; if ($DEBUG_LEVEL >= ($verbosity // 1)) { my $msg = join('', $code->()); print STDERR "DEBUG: ", $msg, "\n" if length($msg); } } # ...the meat of the package is below...

I think I have been able to monkey-patch all the methods in the package, by adding the following to the bottom of the package file:

# ...the meat of the package is above... __dbg { no strict 'refs'; no warnings 'redefine'; my $package = __PACKAGE__; my %patched = ('__dbg' => 1); foreach (grep { defined &{"${package}::$_"} } keys %{"${package}:: +"}) { unless (exists $patched{$_}) { $patched{$_} = 1; __dbg { "Monkeypatching '${package}::$_' for tracing..." } + 5; my $fname = $_; my $fn = \&{"${package}::$_"}; *$_ = sub { __dbg { "Starting ${package}::${fname}(", join(',', @_ +), ')' } 4; my @ret = $fn->(@_); __dbg { "Ending ${package}::${fname} with return value +s: ", join(',', @ret) } 4; return unless defined(wantarray); return @ret if wantarray; return @ret[0] if scalar(@ret); } } } }; 1;

Now, whether this is a good thing to do or not (I promise to remove it at the end of the dev cycle), it seems to be working, but now I'm worried that my 'light-touch' profiling will actually have unintended side-effects on the subs it touches. For example:

  1. It warns on subs that have prototypes (e.g. Prototype mismatch: sub MyModule::method1 (&;$) vs none at /MyModule.pm line Y.), where Y is the closing brace to the unless (exists... block. I can suppress with no warnings 'prototype' but does that mean that the interpreter may no longer apply the syntactic distinctions that prototypes intend to provide?
  2. Even though I'm trying to reflect the requirements of the caller using wantarray, am I altering the results of wantarray in the actual wrapped call? Better to check wantarray first?
  3. I think it's also attaching to subs that are imported into the module (i.e. I don't think try, with or time are actually part of the package), but I can't see the 'best' way to exclude them
  4. (Also, it doesn't actually output the arguments, but I can't see the bug -- should I copy @_ to a local variable first (i.e. my @args = @_)?)

Any other wisdom to be shared here (bar the obvious "don't" and "use a cpan module")?


In reply to Monkey patching all subs with a basic 'starting subname' message by Anonymous Monk

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-24 21:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found