The Perl debugger can be your superpower
Tags: programming, debugging, perl
Published: 2021-03-09 15:14:32

---
title: The Perl debugger can be your superpower
published: true
date: 2021-03-09 15:00:00 UTC
tags: Programming,debugging,Perl
canonical_url: https://phoenixtrap.com/2021/03/09/perl-debugger-superpower/?utm_source=rss&utm_medium=rss&utm_campaign=perl-debugger-superpower
series: The Perl debugger can be your superpower
---

 **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 `print` statements** or logging. “Got value.” “Calling `foo` 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**?

**All of this is possible with a [debugger](https://en.wikipedia.org/wiki/Debugger)**, and Perl has one [built-in](https://perldoc.pl/perldebug). Run your program with `perl -d`, and after a slight delay you’re presented with a new command line prompt:

```shell
% 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](https://perldoc.pl/perldebtut), 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.

And then there’s the [full manual](https://perldoc.pl/perldebug), where you can learn how to do things like [getting a stack backtrace](https://perldoc.pl/perldebug#Stack-backtrace) of all calls leading up to the current 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](https://perldoc.pl/prove#-exec) through its test harness. Run it like this:

```shell
% 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](https://metacpan.org/pod/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](https://metacpan.org/pod/distribution/PSGI/PSGI.pod) applications using [Plack::Test](https://metacpan.org/pod/Plack::Test).)

## A caveat

If you’re debugging and testing your applications strictly through network requests to another process, such as through [Test::WWW::Mechanize](https://metacpan.org/pod/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](https://perl.apache.org/) have a look at [Apache::DB](https://metacpan.org/pod/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 `print`s/run/stop/add more `print`s/run” cycle.

How can you integrate the Perl debugger into your programming workflow? Leave me a message in the comments and let me know.