Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

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

by stevieb (Canon)
on Jul 14, 2017 at 23:35 UTC ( [id://1195143]=note: print w/replies, xml ) Need Help??


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

I responded on that thread, so I'll go another round.

When I first started with Perl, I was dropped into a situation where I had a less-than-sane codebase. The very first thing I desired to design was something that could tell me stuff about code. I got familiar with the tools others have mentioned, but still wanted to figure it out.

Devel::Trace::Subs was the creation of that, after having to go on another huge tangent with Devel::Examine::Subs as its backbone.

This is intrusive; it literally writes to library files:

perl -MDevel::Trace::Subs=install_trace -e 'install_trace(file => "Dat +a::Dump")'

At this point, you've infected your ../Data/Dump.pm file. This is a global example, you can fine-tune what you're tracing. So a script that looked like this:

use warnings; use strict; use Data::Dump qw(dd); three(); sub one { return {a => 1, b => 2}; } sub two { return one(); } sub three { dd two(); }

That output this:

{ a => 1, b => 2 }

...now looks like this:

use warnings; use strict; use Data::Dump qw(dd); use Devel::Trace::Subs qw(trace_dump); $ENV{DTS_ENABLE} = 1; three(); trace_dump(); sub one { return {a => 1, b => 2}; } sub two { return one(); } sub three { dd two(); }

... and outputs:

{ a => 1, b => 2 } Code flow: 1: Data::Dump::dd 2: Data::Dump::dump 3: Data::Dump::_dump 4: Data::Dump::tied_str 5: Data::Dump::_dump 6: Data::Dump::_dump 7: Data::Dump::format_list Stack trace: in: Data::Dump::dd sub: main::three file: script.pl line: 20 package: main in: Data::Dump::dump sub: Data::Dump::dd file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 84 package: Data::Dump in: Data::Dump::_dump sub: Data::Dump::dump file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 36 package: Data::Dump in: Data::Dump::tied_str sub: Data::Dump::_dump file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 292 package: Data::Dump in: Data::Dump::_dump sub: Data::Dump::_dump file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 331 package: Data::Dump in: Data::Dump::_dump sub: Data::Dump::_dump file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 331 package: Data::Dump in: Data::Dump::format_list sub: Data::Dump::dump file: /usr/local/share/perl/5.22.1/Data/Dump.pm line: 65 package: Data::Dump

You can then just revert your changes:

perl -MDevel::Trace::Subs=remove_trace -e 'remove_trace(file => "Data: +:Dump")'

The output is kind of configurable in that there are two very basic templates with the ability to send in an html flag for rendering. You can also limit the output to flow or trace.

There are many other tools that do this kind of thing that are far better and far more widespread, and unless one is brave, they'd use a non-intrusive proper profiler or something that's been through the ropes. I just like how OP is proud of their __dbg() hijacker, so I thought I'd share :)

update: Mentioned Devel::NYTProf as a profiler, but if OP wants to get into examining files/code itself, invest in learning some PPI.

Replies are listed 'Best First'.
Re^3: Monkey patching all subs with a basic 'starting subname' message
by Anonymous Monk on Jul 17, 2017 at 21:48 UTC

    > I just like how OP is proud of their __dbg() hijacker, so I thought I'd share :)

    I feel suitably patted on the head and sent on my way! :)

    __dbg was one of the first things I wrote, so I am fond — not necessarily proud — of it. For me, I just like that it doesn't evaluate the entire code block if the debug level is too low (so I can avoid string-interpolation, etc. if I don't need to see it); that the prototype allows it to achieve this without any significantly obtuse syntax (whereas some other languages I've worked with would want all manner of function () or () => cruft); and that it is distinguishable from any other if/print in the code, by naming convention. I also like to set the debug level via an incremental Getopt::Long, and run it on the command line. Because I can.

    Because that's all I needed -- a basic if/print that I can leave in place and 'turn off' without worrying about it.

    But most of all, I like that I devised both the requirement and the implementation myself. Because it meant I knew enough to commence breaking everything I saw!

    That I used it as part of further attempts to inspect the code I was working on is, of course, an overstretching of its original goals, but all I wanted to do was print the subroutines in the order they were run, without irretrievably changing the original files, so I took my hammer and applied it to this nailish-looking thing.

    I haven't tried either Devel::Trace::Subs or Devel::Examine::Subs but, from what I have read, I don't know if I like that it modifies the files (although I do appreciate that you can revert it). I really didn't want to change the source files, if I could help it — they aren't mine, and it wasn't my box to play with. Thanks for pointing these out, though, and I may look to evaluate them more thoroughly in the future.

    PS: I tried NYTProf very quickly, in response to two recommendations, once I got back to my lab environment. I'm sure it's wonderful but I'm nowhere near needing it yet. nytprofhtml is very pretty and nytprofcalls is very thorough but, if I'd started out with either in my toolchain, I feel I'd still be there now, wondering in what order the subroutines were run in a one-off process I was looking at...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1195143]
help
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: (3)
As of 2024-04-18 22:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found