Debuging method for perl Complex data structures

For complex data structures (references, arrays and hashes) you can use the Data::Dumper

use Data::Dumper qw(Dumper);

print Dumper \@an_array;
print Dumper \%a_hash;
print Dumper $a_reference;

These will print something like this, which helps understand the content of the variables, but shows only a generic variable name such as $VAR1 and $VAR2.

$VAR1 = [
       'a',
       'b',
       'c'
     ];
$VAR1 = {
       'a' => 1,
       'b' => 2
     };
$VAR1 = {
       'c' => 3,
       'd' => 4
     };

I'd recommend adding some more code and printing the name of the variable like this:

print '@an_array: ' . Dumper \@an_array;

to gain:

@an_array: $VAR1 = [
        'a',
        'b',
        'c'
      ];

or with Data::Dumper like this:

print Data::Dumper->Dump([\@an_array, \%a_hash, $a_reference],
[qw(an_array a_hash a_reference)]);

getting

$an_array = [
            'a',
            'b',
            'c'
          ];
$a_hash = {
          'a' => 1,
          'b' => 2
        };
$a_reference = {
               'c' => 3,
               'd' => 4
             };

From:

9 Comments

Data::Printer is another alternative.

To say it more clear that echowuhao:

Data::Printer is actually a "better" alternative if you just need to have nice printouts of data with coloring to guid your eye and some smart auto detection.

Data::Dumper is good when you need something reliable (long history and often used) and if you might want to read this data back in into perl structures. (e.g. with eval)

If you have complex structures to debug Data::Dumper::Concise can be good.

http://search.cpan.org/~frew/Data-Dumper-Concise-2.020/lib/Data/Dumper/Concise.pm

I need to examine deep, complex objects in debug every day, so I came up with my_dumper. It takes a name string, and a ref, and has some additional options, such as to limit depth.

You can also see the Doxygen that goes with it.

(Apologies for not figuring out the syntax highlighting markup needed for this site. Seems it's not important enough to link to?)

# @function my_dumper()
# Print out an object or data structure to STDERR.
# Sleeps proportional to object size, to avoid interlaced messages from other STDERR writes.
#
# Usage:
#
# my_dumper( 'name' => q/$self->{$Test}/, 'dumpling' => $self->{$Test}, 'depth' => 2, 'line' => __LINE__ );
#
# @par 'name' => 'name or description of object'
# @par 'dumpling' => 'object'
# @par 'depth' => 'dump depth, 0 is all (optional)'
# @par 'line' => __LINE__ (optional)
# @par 'indent' => indent_value (0:none, 1:fixed, 2:readable, 3:with comments)
# @par 'sort' => sortval (0 is no sort; 1 is builtin sort; subref taking hashref, return keylist)
sub my_dumper {
    use Data::Dumper;
    my %defaults = ( 'depth' => 0, 'name' => 'unknown');
    my %p = (%defaults, @_);
    $Data::Dumper::Maxdepth = $p{'depth'};
    $Data::Dumper::Indent = ($p{'indent'} // 1);
    $Data::Dumper::Sortkeys = ($p{'sort'} // 1);
    my $dumpling = Dumper( $p{dumpling} );
    my $dumpling_length = length( $dumpling );
    my ($package, $file, $line, $sub) = caller(1);
    if ( defined $p{'line'} ) {
        $line = $p{'line'};
    } elsif ( not defined $line ) {
        if ( defined $p{'line'} ){
            $line = $p{'line'};
        } else {
            $line = 'unknown';
        }
    }
    my $sleep_time = int(length($dumpling)/1e6 + 1);
    print STDERR "Sleeping $sleep_time seconds before dump\n";
    sleep $sleep_time;
    print STDERR "Dumpling length = $dumpling_length\n",
                 "$file, $package, $sub ($line) *** $p{name} ***\n", $dumpling,
                 "Sleeping $sleep_time seconds after dump\n";
    sleep $sleep_time;
}

Are any of my comments getting through? There's no indication, just a new blank comment field. (At least it's not saying I have to logout and back in again because my session timed out.)

Getting any text posted here is a minor achievement. I think you can do syntax highlighting by using both "code" and "pre" tags, but checking this by using "preview" would probably either not work or log me out. People have also embedded iframes to other sites to do syntax highlighting. (And yes, my session had expired when I tried to post this. This site is pathetic.)

I have been using
use Data::Dump qw(dump);
and finding it to be excellent in most circumstances.

I never use Data::Dumper. Depending on circumstances, I use Data::Printer or Data::Dump.

FYI Ross, Data::Dump exports 'dd' by default which is easier to remember and type and also avoids accidental coredumps if you forget to explicitly import 'dump'.

Data::Dumper is like a trusty dog. Always there, a reliable friend, licks his backside more often than I'd like after I ask him to print out a particularly complex data structure or object…

For most things, I'm now using Data::Printer...

Data::Printer is actually a "better" alternative if you just need to have nice printouts of data with coloring to guid your eye and some smart auto detection

It's not just pretty, but damn if it isn't powerful[1], customizable[2] and seriously eyeball-[3] and keystroke-saving[4]. Read just the author's Features section, if you're unfamiliar with DDP. It's some seriously deeply thought out software that has changed the way I work with my code.

[1] - See fiddling filters with Data::Printer::Filter. Also see `class_method` in Making your classes DDP-aware.

[2] - Love the .dataprinter config file!

[3] - Colorized output! Ability to completely transform, simplify or even eliminate printing of certain problematic branches of a structure with filters!

[4] - I so love pass thru p()

Leave a comment

About flymike

user-pic Keep it simple, stupid.