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;
}

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'.

Leave a comment

About flymike

user-pic Keep it simple, stupid.