We’ve all been there: Deep in the bowels of a program, trying to figure out why something’s not working right.
Maybe a variable isn’t getting the right value. Maybe a function or method isn’t getting called or has the wrong arguments. Maybe we don’t even know if a line of code is being reached.
So what do we do? We litter our code with
x.” “Reached line 42.”
And then we have to make sure to clean it all out, lest these informal clues make their way to production and the eyes of users.
There’s a better way
What if I told you that you could freeze time in the middle of your program and examine all these details while they happen, or even before they happen? That you could be alerted when variables or expressions changed and immediately dive in to see the cause? That you could even run exploratory test code and play “what if” scenarios?
% perl -d hello.pl Loading DB routines from perl5db.pl version 1.57 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::(hello.pl:7): say 'Hello world!'; DB<1>
Before you go any further, you might want to know how to exit the debugger. Just type
q and then press Enter and you’ll be back at your normal command line.
Perl also comes with a good (if incomplete) tutorial on using the debugger, and I suggest you work through that to familiarize yourself. It will tell you how to get help, list and view variables and lines of code, set breakpoints, and step through line by line.
My favorite debugging trick
By far my favorite thing to do with the debugger is to run it against test scripts using the
prove command. This takes advantage of
prove’s ability to run an arbitrary interpreter through its test harness. Run it like this:
% prove --verbose --lib --exec 'perl -Ilib -d' t/foo.t
…and you’ll be able to step through the test script at
t/foo.t, loading any necessary modules from the
lib directory, getting verbose test output along the way.
This is extremely helpful when paired with modules like Test::Mojo, which can load Mojolicious web application classes and then exercise them using its own user agent. (You can do similar things with other PSGI applications using Plack::Test.)
If you’re debugging and testing your applications strictly through network requests to another process, such as through Test::WWW::Mechanize, running the debugger will only show you the client-side of things and not allow you to step through execution of the server side. This is especially prevalent among legacy apps not using the PSGI protocol. If you’re using Apache mod_perl have a look at Apache::DB, which enables you to run the Apache
httpd web server with the interactive debugger.
So what’s your superpower?
A debugger is a common feature in many languages and development environments, and Perl has had one for decades. Yet I’m constantly surprised that more developers don’t know about or don’t use this powerful tool that can cut through the “add
How can you integrate the Perl debugger into your programming workflow? Leave me a message in the comments and let me know.