Data::Dumper Debugging

I've never really used the Perl debugger much (maybe I should learn?) and usually resort to lots of use Data::Dumper; print Dumper($somevar); statements to help me understand what's going wrong with a piece of code.

However, what I often find is that $somevar contains exactly the data I expected it to contain. So the problem must be another variable? Or maybe there's a function which isn't returning what I expected it to? Or maybe one of my if statement has jumbled logic? So I need to change my print Dumper(...) statement and re-run the script.

Anyway, sick of that, and inspired by a question on StackOverflow I've released Pry, a really tiny wrapper around DOY's Reply REPL. Using Pry, you can run your script, and drop into a REPL at the point where you suspect things are going wrong. Once in the REPL you can inspect any lexical variables which are in scope (thanks, PadWalker!), or peek at the call stack (thanks, Devel::StackTrace!); you can even call functions and methods to see what's going on.

So if you, like me, have never managed to figure out breakpoints, and watches, and whatever other thingies a proper debugger has to offer, but are getting frustrated by the limitations of Data::Dumper-based debugging, give Pry a try!

17 Comments

Neat. There is actually a simple way to do this in the debugger though. You can just put $DB::single = 1; in your code where you want it to stop and drop into the debugger shell.

Nice, although I wouldn't write

use Data::Dumper; print Dumper($somevar);

in the first place, I'd write:

use Data::Dump; dd $somevar;
or:
use Data::Printer; p $somevar;

...which are not only more convenient to type, but also produce much prettier output.

Have you taken a look at Carp::Reply?
I've used it to similar effect, probably worth a SEE ALSO.

Data::Printer outputs to STDERR which means you can't pipe the output to a pager without extra work. At that point Data:Dumper ends up requiring less typing.

@Toby Inkster

You're right, Data::Printer has some quirks.
The prototype thing is a trade-off; it allows p to treat an array variable with a single value differently than a scalar variable, and an array differently than a hash -- with the downside that you can only dump actual variables, not the results of anonymous expressions.

Give Data::Dump a try if you want something closer to the Data::Dumper experience but with less typing and with cleaner/terser output (and in particular, no silly "$VAR1 =" noise in the output).


@Matt Perry

Technically, adding the four characters "2>&1" to the command-line is less typing overhead than the difference between a single "print Dumper" vs "p"... :)
Not to mention it adds up if you want to use multiple dump statements in your code.
But you may have a point if you're working in an IDE that makes it annoying to temporarily change the way perl is called for test runs of the script.

When your 'finger memory' automatically types '2>&1' then it is just as fast as '|&' :-)

Dude, you should totally learn the Perl debugger.

I'm running OSX 10.8 and I have:

GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)

Hi everyone! I see some of the discussion got a bit sidetracked towards Data::Printer. On this matter, I just wanted to point out that I really appreciate all the enthusiasm and feedback you guys have >shown, and that because it is so hard to please everyone I've built it so you would create a ~/.dataprinter file with your own preferences and never have to worry about it again :)

@tobyink for the issues that you have pointed out, I'd make it like so and never worry about it ever again:

  {
    use_prototypes => 0,
    return_value   => 'pass',
    deparse        => 1
    class => {
      inherited => 'public',
    },
  };

@mattperry for sending the output to stdout you can use a similar .dataprinter file as above, but also adding "output => 'stdout'".

I really wish you guys would give DDP another try and let me know if there is anything I can do in future releases to make it better!

As for Pry, I really liked it, but like Samuel Kaufman said here, I wonder how different it is from Carp::Reply itself. You mentioned it only works when exceptions are thrown, but Carp::Reply let's you put "Carp::Reply::repl();" anywhere in the code and then resume it with Ctrl-D, just like your "pry" command does. Or did I get it wrong?

Toby Inkster:
|& is only inherited from csh, |& in ksh is for co-process creation. So the reason people don't reach for it is perhaps because it is non-standard, non-portable and incompatible. And (luckily) not every /bin/sh is a /bin/bash

Leave a comment

About Toby Inkster

user-pic I'm tobyink on CPAN, IRC and PerlMonks.