Improving Perl debugger variable output
TL;DR: Drop my .perldb file in your home directory for a much nicer debugger experience.
The kindest thing I can say about the built-in Perl debugger is that it doesn't drink even though it's old enough to. Using it is painful but there are many things you can do to make it nicer. Heck, I even had syntax highlighting working once.
One of my major pet peeves with the debugger has been how it dumps variable data. Have you ever used it and typed "x $dbic_object
" or "r
" to return from a method and gotten hundreds of lines of near useless output spewing across the screen? To make matters worse, it takes a long time to dump all of that, making the slow debugger even slower than normal. It's very frustrating. Here's how to fix it.
When running the debugger, Perl loads a script named perl5db.pl
and internally, when it needs to dump some variables to the terminal, it runs some code which looks like this (edited for clarity):
# If main::dumpValue isn't here, get it.
do 'dumpvar.pl' || die $@
unless defined &main::dumpValue;
# must detect sigpipe failures - not catching
# then will cause the debugger to die.
eval { main::dumpValue(@vars); };
# The die doesn't need to include the $@, because
# it will automatically get propagated for us.
if ($@) {
die unless $@ =~ /dumpvar print failed/;
}
If you read that carefully, you'll realize that if there's a dumpValue()
function in main::
, that's what the debugger will use to dump out your variables. The old dumpvar.pl
code was written back when 5.001 was still around and fortunately shoves things in the dumpvar
package, but we still have dumpValue()
littering main::
.
However, we can make life much easier with this. By creating your own .perldb
file in your home directory (I have a fully documented example here), you can add this to it:
# use a different package in case you need to
# define other helper functions here
package My::Debugger;
use Data::Printer sort_keys => 1, colored => 1;
# this is usually set by dumpvars.pl (called from the debugger). But if it's
# already defined, the debugger uses our version
sub ::dumpValue {
my ( $value, $maxdepth ) = @_;
p $value;
}
With that, you'll get nice, clean Data::Printer output (or whatever you want to put in there).
Thanks for sharing this!
I have adopted your .perldb, and I like it a lot. With a one line change it also works in an Emacs perldb session (yes, I'm guilty of not only using the debugger, but also Emacs):
Emacs shows the current source in a window, which collides with the 'v' command - but also makes it unneccessary.
haj,
Sorry, didn't see this comment earlier. Thanks for the patch! I've added it and credited you.
Best,
Ovid