Using the Perl debugger with DBIx::Class

I wrote about using the Perl debugger with Moose. In that post, I showed how to use DB::Skip to make it easier to use the Perl debugger with Moose and other modules whose guts you don't want to wade through.

Today's debugger hack will make using the debugger with DBIx::Class much easier.

If you're a fan of the debugger, one thing which makes life miserable is being in the debugger and accidentally doing something like this:

121:        local config(qw'logging LogEvent')->{Exchange} = 1;
122:    $DB::single = 1;
123==>      my $wallet = $character->wallet;
124 
125:        my $exchange = $class->new(
126             principal => $character,
127             slug      => 'test_check_success',
128             steps     => [ [ TestWallet => check => $character => $wallet ] ]
129         );
  DB<2> x $character

With that, you get hundreds of lines of output scrolling past, too fast to read. And forget about going back in your buffer trying to find the data you need. It's a nightmare.

So I hijacked the p command in the debugger. In perldoc perldebug, we see that p is for this:

p expr

Same as print {$DB::OUT} expr in the current package. In particular, because this is just Perl's own print function, this means that nested data structures and objects are not dumped, unlike with the x command. The DB::OUT filehandle is opened to /dev/tty, regardless of where STDOUT may be redirected to.

To be honest, I don't find that very useful. So I altered it to make a quick "dump" of a data structure, with one interesting caveat. Unless it's an array or hash reference, it's stringified. So the above debugging session becomes this (I've truncated some data to hide some important gameplay):

121:        local config(qw'logging LogEvent')->{Exchange} = 1;
122:    $DB::single = 1;
123==>      my $wallet = $character->wallet;
124 
125:        my $exchange = $class->new(
126             principal => $character,
127             slug      => 'test_check_success',
128             steps     => [ [ TestWallet => check => $character => $wallet ] ]
129         );
DB<2> p $character
Veure::Model::DB::Character=HASH(0x7fcd6feb5de8)
DB<3> p {%$character}
{
'_column_data' => {
    'agility' => '10',
    'arrival' => '2017-03-27 09:44:33.546391000+0000',
    'career_path_id' => '',
    'character_id' => '15538',
    'conscious' => '1964-01-22 00:00:00+0000',
    'curr_agility' => '1',
    'curr_intelligence' => '1',
    'curr_social' => '1',
    'curr_stamina' => '1',
    'curr_strength' => '1',
    'current_ship_id' => '',
    'experience' => '800',
    'focus' => '1',
    'genotype_id' => '1',
    'intelligence' => '10',
    'inventory_id' => '17762',
    'last_activity' => '2017-03-27 09:44:33+0000',
    'last_station_area_id' => '1199',
    'modifier_list_id' => '',
    'name' => 'winston',
    'slug' => 'winston',
    'social' => '10',
    'stamina' => '10',
    'station_area_id' => '1199',
    'strength' => '10',
    'user_id' => '14554',
    'wallet' => '10'
},
'_dirty_columns' => {},
'_ignore_messages' => '0',
'_in_storage' => '1',
'_inflated_column' => {
    'arrival' => '2017-03-27T09:44:33',
    'conscious' => '1964-01-22T00:00:00',
    'last_activity' => '2017-03-27T09:44:33'
},
'_rel_in_storage' => {},
'_relationship_data' => {
    'bank_account' => 'Veure::Model::DB::BankAccount=HASH(0x7fcd6fec3460)',
    'character_user' => 'Veure::Model::DB::User=HASH(0x7fcd6fed6f08)',
    'inventory' => 'Veure::Model::DB::Inventory=HASH(0x7fcd71137110)'
},
'_result_source' => 'DBIx::Class::ResultSource::Table=HASH(0x7fcd6b7ce350)',
'app' => 'Veure::App=HASH(0x7fcd6b79aa08)',
'related_resultsets' => {}
}

Now dumping that data structure is actually useful and it's trivial for me to find the information I need!

You can get the source of my debugger hack here. Save that as .perldb in your home directory.

Hire Us!

As always, if you want top-notch software development or training, or help building your test suite, drop me a line at ovid at allaroundtheworld.fr. Most of us are Perl devs, but we also do front-end development, Golang, C++, Lua, and Python. Due to our extensive links in multiple software communities, if you need an expert in another language, let me know.

1 Comment

I would like to see more development of debugger hacks using .perldb. Maybe we can turn this into a module on CPAN, or at least a namespace on CPAN so we can add stuff like this in a standardized way. I've got saveable breakpoints using .perldb: https://blogs.perl.org/users/matthew_persico/2016/12/saving-breakpoints-in-the-perl-debugger.html

Leave a comment

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See http://www.allaroundtheworld.fr/ for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book! http://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/