A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Make "x" use Data::Dumper in the Perl debugger

tldr:

$DB::alias{x} = 's/^x\s+(.*)/p Data::Dumper::Dumper($1)/';

Thanks Jim

Full article:

In the guts of the script that runs the Perl command-line debugger (accessible whenever you start a perl script with the '-d' command-line argument), there lives a hash, accessible globally as %DB::alias.  Whenever you enter a command at the debugger command line, the first word in the command is looked up in %DB::alias, and if it is found, the corresponding value is used as a substitution pattern against the entire command line.  The substituted line is then processed as usual.  The examples and explanation in the perldebug man page don't make this terribly clear.  The actual code that is executed by the debugger (after stuffing the first word in the command line into the variable $i) is:

eval "\$cmd =~ $alias{$i}";

This can be used to completely customize the debugger.  For example, the ordinary output of the debugger's built-in "x" command is pretty ugly.  Substituting a different formatter (such as Data::Dumper::Dumper) can be accomplished with the following alias:

$DB::alias{x} = 's/^x\s+(.*)/p Data::Dumper::Dumper($1)/';

This converts the line "x $something" into the line "p Data::Dumper::Dumper($something)".  Incidentally, solving this particular problem was the impetus for this blog post.
More extensive customization is possible.  For instance, alias substitution occurs once in the stock debugger.  Armed with the knowledge of how alias substitution works, you can create an alias that expands aliases iteratively like this:

my $in_exp = 0;
sub expand_db_aliases
{
     die "Recursively expanding the expansion alias" if $in_exp++;
     my $cmdref = shift;
     my $exp_cnt = 0;
     while($cmdref =~ /^(\S+)/ and $DB::alias{$1})
     {
          my $i = $1;
          die "Alias expansion exceeds 100 iterations" if $exp_cnt++ > 100;
          my $cmd = $$cmdref;
          package DB;
          eval "\$cmd = $alias{$i}";
          die $@ if $@;
          $$cmdref = $cmd;
     }
     $in_exp--;
} ;
$DB::alias{exp} = '//; expand_db_aliases(\$cmd);';

The heavy lifting is done in the expand_db_aliases subroutine, which matches the actual instructions used by the debugger to expand aliases as closely as possible.

Loading your customizations automatically

If there is a file named ".perldb" in your home directory, the Perl debugger will load it and interpret its contents as Perl code after it initializes itself.  You can put any code-based customizations you desire into this file.  You can (and should) also use this file to load any dependencies required by your customizations.  For the replacement "x" command, I added the following to my .perldb file:

use Data::Dumper;
$DB::alias{x} = 's/xx\s+(.*)/p Data::Dumper::Dumper($1)/';