Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
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:
Any other wisdom to be shared here (bar the obvious "don't" and "use a cpan module")?
|
|---|