Finding Unused Perl Variables

by · ·updated ·3 min read ·472 words
Table of Contents

✨ This post was last updated on September 15, 2026

#The Problem

I’ve been working on some linting projects at $work and one thing I’m working on is finding unused variables in our codebase. This can be pretty important in a larger codebase. When you find variables which have not been used, you may find yourself asking, “why is this here?” and you may not easily get an answer. Eliminating unused variables can be good for the performance of the code, but also good for everyone else on your team. So, we want to make sure we can remove old bits of unused code and also prevent new cases.

One tool we have used for this is Test::Vars. It has some limitations (like it needs to be in a file with a package declaration) and it has some bugs, but it does find some unused variables.

Abandoned Pennsylvania Route 61

"Abandoned PA 61 (2019)" by Mr. Matté is licensed under CC BY-SA 3.0 .

#App::perlvars

As part of this work, I have released App::perlvars. It’s simple to use. Just install the module and then run it on the .pm files in your code:

find lib | grep pm$ | xargs perlvars

You can exclude arbitrary variables so that they don’t get flagged. See the documentation for more info on that.

#Variables::ProhibitUnusedVarsStricter

If you use Perl::Critic, I highly encourage you to look at Perl::Critic::Policy::Variables::ProhibitUnusedVarsStricter as well. This may be an even better solution, or you may find that using both tools gives you the maximum benefit. To start with, you can try something like this:

perlcritic --single-policy Variables::ProhibitUnusedVarsStricter lib

#Test::Vars

Added to this, you can also use Test::Vars directly as part of your test suite.

#precious

If you’re setting up code quality checks, I highly recommend precious. It’s a configurable code quality harness that can run multiple linters and tidiers from a single configuration. You can add perlvars as a lint command in your precious.toml:

[commands.perlvars]
type    = "lint"
include = ["**/*.pm"]
cmd     = ["perlvars"]
ok-exit-codes = [0]
# perlvars exits 255 (not 1) when it finds unused/single-use variables.
lint-failure-exit-codes = [255]

The lint-failure-exit-codes setting is important: perlvars exits with 255 (not 1) when it finds unused or single-use variables, so precious needs to be told to treat 255 as a lint failure rather than an error.

This leaves you with plenty of options for code quality checks in general and for finding unused variables in particular.

Deprecated Code::TidyAll is deprecated — use precious instead

#Code::TidyAll::Plugin::Test::Vars

If you’re a tidyall user, I encourage you to look at Code::TidyAll::Plugin::Test::Vars. While you’re at it, enable the Code::TidyAll::Plugin::PerlCritic plugin, add Perl::Critic::Policy::Variables::ProhibitUnusedVarsStricter to your .perlcriticrc and you’ll have maximum unused variable checks.

#Test::Code::TidyAll

Once you’re using tidyall, you can use Test::Code::TidyAll to ensure code quality within your test suite. Dist::Zilla users can also do this via Dist::Zilla::Plugin::Test::TidyAll.

// end deprecated section