The 2004 Perl Advent Calendar
[about] | [archives] | [contact] | [home]

On the 8th day of Advent my True Language brought to me..
Data::Dumper::Simple

When I'm debugging, the one module I can't do without is Data::Dumper. The ability to print out what a variable contains recursively is invaluable. It's one of the nine indispensible rules of debugging: Quit Thinking and Look. No matter what I think a variable must contain, there's no substitution for quickly getting in there and printing it out to just make sure.

Data::Dumper::Simple provides a slight, but significant, improvement over Data::Dumper. It automatically prints out the name of the variable you're dumping. This may seem trivial, but in a situation where you're concentrating your hardest in tracking down a problem the last thing you want to be doing is getting confused about which Dumper statement is which. And, admit it, we're all too lazy to add the extra information to the print statement by hand - but that's okay, laziness is a virtue in the Perl world - especially when we're so lazy we get a module to do it for us.

Let's remind ourselves just how useful Data::Dumper is. First we'll set up some variables:

  # create some data structures
  my $foo = "wibble";
  my %bar = ( boston => "cheers", space => "ten forward" );
  my @baz = ( "red", [ "green", { yellow => "blue" } ] );

Then later on we'll print them out.

  use Data::Dumper;
  print STDERR Dumper($foo, \%bar, \@baz);

We get a print out showing us well formatted versions of the data structures we fed in:

  $VAR1 = 'wibble';
  $VAR2 = {
            'space' => 'ten forward',
            'boston' => 'cheers'
          };
  $VAR3 = [
            'red',
            [
              'green',
              {
                'yellow' => 'blue'
              }
            ]
          ];

This is great! Anywhere we want in our code whenever we want to see what a variable contains we can just print it out. And we can sprinkle these all over our code so we can tell what things are, and track when we made the mistake...

...apart from the fact we'd never be able to tell which variable is which because they're only labeled $VAR1, $VAR2, and $VAR3. As soon as we start using multiple Dumper commands the whole thing is going to get confusing. Of course we could - if were prepared to type a lot more in our statements - label all our Data::Dumper output with whatever we wanted. However, what we really want is to have the correct labels automatically with no extra effort. Data::Dumper::Simple comes to the rescue:

  use Data::Dumper::Simple;
  print STDERR Dumper($foo, \%bar, \@baz);

This - through clever use of source filters - prints out some output that is labeled with the names of the variables that we were dumping out:

  $foo = 'wibble';
  $bar = [
           'boston' => 'cheers',
           'space' => 'ten forward'
         ];
  $baz = [
           'red',
           [
             'green',
             {
               'yellow' => 'blue'
             }
           ]
         ];

And that's all there is to it. A simple improvement for one of the common uses of Data::Dumper.

We can take things a little further. You'll note that the funny characters at the front of the variable names have all changed to $. That's because we're passing both %bar and @bar by a reference. We need to do this because the Data::Dumper Dumper function will get it's arguments flattened by the list calling convention. If we'd written:

  use Data::Dumper;
  print STDERR Dumper($foo, %bar, @baz);

We'd have got:

  $VAR1 = 'wibble';
  $VAR2 = 'boston';
  $VAR3 = 'cheers';
  $VAR4 = 'space';
  $VAR5 = 'ten forward';
  $VAR6 = 'red';
  $VAR7 = [
            'green',
            {
              'yellow' => 'blue'
            }
          ];

As all the variables are smooshed together indistinguishably by the time they reach the Dumper function. Data::Dumper::Simple is a little more clever than that. Calling:

  use Data::Dumper::Simple;
  print STDERR Dumper($foo, %bar, @baz);

Prints out exactly what we might expect:

  $foo = 'wibble';
  %bar = (
           'boston' => 'cheers',
           'space' => 'ten forward'
         );
  @baz = (
           'red',
           [
             'green',
             {
               'yellow' => 'blue'
             }
           ]
         );

Meaning it's even quicker to get some useful debug information out.

  • Data::Dumper
  • Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems