Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Data::Dumper(::Simple) is your friend

by cajun (Chaplain)
on Jul 05, 2005 at 01:34 UTC ( [id://472337]=perlmeditation: print w/replies, xml ) Need Help??

For a long time on PM I have seen people saying "use Data::Dumper" and look at your data. When I have seen this, I've always wondered why do I need to use a module to look at my data when it is so easy to print the data without a module.
foreach (@array){ print "$_\n"; } foreach (sort keys %hash){ print "$_ $hash{$_}\n"; }

For the past couple of days I have been working on a piece of code that I just could NOT figure out why I was getting "Use of uninitialized value....". I used the snippet above several times. I wrote short scripts to prove to myself my code was working. Yet, in the actual script, the same code would not work.

My hash looked something like this:

1111 Fred 2222 Wilma 3333 Barney 4444 Betty
I struggled with this for a couple of days trying to see what was going on. Why was I getting this mysterious 'undef'. I thought about using Data::Dumper as I had seen so many times here. But I didn't get around to it until today.

I put in Data::Dumper::Simple and within 2 minutes saw the issue. My data that I thought looked like the above, really looked more like this:

'1111 ' -> 'Fred' '2222 ' -> 'Wilma' '3333 ' -> 'Barney' '4444 ' -> 'Betty'

There was a trailing space in my keys. I would probably have never located this problem without Data::Dumper.

Data::Dumper(::Simple) is my new friend

I guess lessons learned the hard way are the ones you remember most easily.

M

Update: Thanks itub and Nkuvu. Both very good points. Using delimiters around the variables is an excellent idea that I will remember. Thanks.

Replies are listed 'Best First'.
Re: Data::Dumper(::Simple) is your friend
by itub (Priest) on Jul 05, 2005 at 02:43 UTC
    I love Data::Dumper and use it all the time, but I think that's not the lesson here. The real lesson is that whenever you print out a value for debugging, you should use clear delimiters. I often do the following:
    print "foo=($foo)\n";

    You can use whatever delimiters you want, of course, and the best delimiter depends on the kind of values you expect.

Re: Data::Dump::Streamer is your friend
by demerphq (Chancellor) on Jul 05, 2005 at 08:40 UTC

    Theres also Data::Dump::Streamer which has various advantages over Data::Dumper and modules that wrap it like Data::Dumper::Simple. Also Data::EasyOO is worth a look although it too currently wraps Data::Dumper.

    The main differences are that Data::Dump::Streamer is more accurate, and does a breadth first dump instead of a depthfirst dump. This usually means dumping recursive structures produces output that is much easier to read. It also tries a lot harder to make the output look readable by making things line up nicely and is lower in terms of memory use for many scenarios as it can stream its output to a filehandle avoiding the need to construct the full dump output in memory (which usually requires more than twice the memory of the original strucutre and on some systems requiring massive ammounts of memory copying.)

    ---
    $world=~s/war/peace/g

Re: Data::Dumper(::Simple) is your friend
by Nkuvu (Priest) on Jul 05, 2005 at 03:25 UTC
    For simple data types, like an array or a hash, it's just as easy to print out the values yourself (with delimiters).

    But Data::Dumper really shines when you have a hash-of-hashes-of-arrays-of... you get the idea. If you have a hash of hashes, you could use the code

    for my $first_key (sort keys %hashiness) { print "$first_key =>\n"; for my $second_key (sort keys %{$hashiness{$first_key}}) { print "\t$second_key\n"; } }

    or you could just do

    print Dumper(%hashiness);

    It gets comparatively easier to use Data::Dumper rather than your own print statements as your data types increase in complexity.

Re: Data::Dumper(::Simple) is your friend
by monarch (Priest) on Jul 05, 2005 at 06:50 UTC
    Just lately I have come to depend on Data::Dumper a lot, particularly as I'm developing in a web environment where running a debugger is not practical.

    I've come to often quickly add the following into a block of code:

    { use Data::Dumper; print( Dumper( \%hashvariable ) ); }
    I put braces around just out of habit.

    Note that I put the backslash in front of the hash reference, for some reason that results in a clearer-to-read output from Dumper than just Dumper( %hashvariable ).

    When in a web environment (such as Mason) I use the following to dump my variables:

    { use Data::Dumper; $m->out( '<pre>' . Dumper( \%hashvariable ) . '</pre>' ); }
      When I debug Webapplications I use Data::Dumper and CGI::Carp like this:
      use CGI::Carp qw/fatalsToBrowser warningsToBrowser/; use Data::Dumper; # ... die Dumper $cgi;
        I hope you have some way of conditionally removing the CGI::Carp line in production. Otherwise anyone who finds a security hole can use it to debug their attack on your code. That can turn minor security breaches into big ones very, very quickly.

        Google for advice on SQL Injection attacks to see a practical example of how attackers can use this debugging information to make their job a lot easier.

      We do a similar thing in our dev environment with Template::Toolkit. We have a flag that gets set automatically so all Template data structures get dumped at the bottom of the page when running in dev, but in QA and Prod it's turned off. It can be very useful when debugging strange data or param issues.
Re: Data::Dumper(::Simple) is your friend
by jimX11 (Friar) on Jul 06, 2005 at 01:04 UTC

    What you need is well-architected logging: Log statements in your code and a logging package like Log::Log4perl providing a "remote-control," which allows you to turn on previously inactive logging statements, increase or decrease their verbosity independently in different parts of the system, or turn them back off entirely. Certainly without touching your system's code -- and even without restarting it.

    That's a quote from the perl.comarticle about Log::Log4Perl.

Re: Data::Dumper(::Simple) is your friend
by tlm (Prior) on Jul 06, 2005 at 03:42 UTC
      use Data::Dump::Streamer; my $hashref = { eenie => 1, meenie => 2, minie => 3, moe => 4 }; print "With Data::Dump::Streamer:\n", Dump( $hashref ), "\n\n"; __END__ With Data::Dump::Streamer: $HASH1 = { eenie => 1, meenie => 2, minie => 3, moe => 4 };
      ---
      $world=~s/war/peace/g

      With Data::Dumper::SLC { eenie => '1', meenie => '2', minie => '3', moe => '4', }

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: Data::Dumper(::Simple) is your friend
by InfiniteLoop (Hermit) on Jul 08, 2005 at 14:12 UTC
    For web applications, printing to the STDERR helpful, as in you could tail the error log while you execute a cgi:
    print STDERR Dumper($foo);

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://472337]
Approved by blokhead
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-03-28 23:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found