While I know I'm in the minority, I use the Perl debugger quite a bit. In fact, I've hacked on perl5db.pl more than I can to admit and it's a mess. However, on a day-to-day basis, I use it constantly and have it bound to ,d in my vim setup. Unfortunately, I also write a lot of Moose code and that's when I invariably hit things like this:

Class::MOP::Method::Wrapped::CODE(0x62b0250)(/usr/local/lib/perl/5.10.1/Class/MOP/Method/Wrapped.pm:91): 91: sub { $modifier_table->{cache}->(@_) }, auto(-1) DB<2> v 88 }; 89: $_build_wrapped_method->($modifier_table); 90 return $class->SUPER::wrap( 91==> sub { $modifier_table->{cache}->(@_) }, 92 # get these from the original 93 # unless explicitly overridden 94: package_name => $params{package_name} || $code->package_name, 95 name => $params{name} || $code->name, 96 original_method => $code, 97

That's not code I've written; that's code that you get when you use Moose and it makes debugging much harder than it needs to be.

Today I decided to do something about that, but I was very pleased to see that Christian Walde already did it for me. Now debugging Moose is a breeze.

The first thing you do is install DB::Skip. This module uses a minimally invasive monkey-patch to the debugger to allow you to ignore packages or subroutines in the debugger. For some reason I couldn't install it directly with the cpan or cpanm clients, so I downloaded and tried to build it manually, but it hung on t/basic.t . I popped it open in vim, hit ,t (my binding for running the current test in verbose mode) and it passed just fine. Weird, but I didn't look into it further. I simply installed it and the altered my $HOME/.perldb file.

If you're not familiar with $HOME/.perldb , this file is documented in perldoc perldebug and let's you run code before the debugger and do all sorts of interesting customizations. For example, you could bind a key in your editor to insert $DB::single = 1; before the current line, set the DEBUGGING environment variable and then have this in your $HOME/.perldb file:

sub afterinit { push @DB::typeahead, "c" if $ENV{DEBUGGING}; }

That would cause your debugger to automatically c ontinue until the first break point (in other words, run until it hits the $DB::single your editor just inserted).

Previously, my rc file looked like this:

sub DB::afterinit { no warnings 'once'; # give me a window of lines instead of a single line push @DB::typeahead => "{{v" unless $DB::already_curly_curly_v++; }

Now it looks like this:

my $skip; BEGIN { $skip = '^(?:Moose|Eval::Closure|Class::MOP)' } print STDERR <<"END"; Debugger skipping: /$skip/ See ~/.perldb if you don't like this behavior. END use DB::Skip pkgs => [ qr/$skip/ ]; sub DB::afterinit { no warnings 'once'; # give me a window of lines instead of a single line push @DB::typeahead => "{{v" unless $DB::already_curly_curly_v++; }

That DB::Skip setup automatically skips any packages in the following namespaces:

Eval::Sandbox

Moose

Class::MOP

Now when I try to debug my Moose classes, the debugger just shows me code that I wrote, not any of the Moose internals. While I'm sure I may find some other packages I'll want to add to my setup, this has tremendously sped up my code debugging. Thanks Mithaldu!

If you'd like to learn more about using the debugger, though it's brief, I do give an introduction to it in my book, Beginning Perl.