I clean my office every couple of months. Despite a decent filing system for paperwork, a day-of-the-month accordion folder for bills and appointments, and every good intent to organize papers and books out of piles, stuff piles up on my desk until I start to lose things. Right now, if I want to take notes on a manuscript (or outline a book in pen), I have to clear off a section my desk.

Tidiness is important to working effectively. It's easier to do good things if you're not working around random debris.

As this is with my desk, so it is with code.

I can't give you a magic incantation to turning thousands of lines of spaghetti code into a well-formatted program that's easy to read, easy to understand, easy to maintain, and easy to extend, but I can explain a couple of Perl 5 tools which will help.

Perl::Tidy

The Perl::Tidy module improves the formatting of messy Perl code. There are myriad options available, but by default it's pretty good -- so good, in fact, that my ~/.perltidyrc file contains only two lines:

-ci=4 -bl

You can run the included perltidy program from the command-line:

$ perltidy my_messy_code.pl

... or you can add a macro or plugin to your editor to tidy code for you. Padre has a plugin called Padre::Plugin::PerlTidy. I have two Vim macros:

map ,pt <ESC>:%! perltidy<CR> map ,ptv <ESC>:'<,'>! perltidy<CR>

If I type ,pt , Vim will run perltidy on the entire file. If I select a region and type ,ptv , Vim will run perltidy on the selection.

This is my first line of defense against poorly-formatted code. Better formatting often helps clarify logic and logic errors.

B::Deparse

Sometimes it's more important to see how Perl interprets code than to suss it out for yourself, especially given complex expressions. The core module B::Deparse takes a program that Perl 5 has already parsed and turns it back into source code.

You can run it from the command line:

$ perl -MO=Deparse some_bad_program.pl

... or on a specific subroutine within a file:

$ perl -MO=Deparse,a_real_mess some_bad_program.pl

... or within a Perl 5 program itself:

use B::Deparse; my $bdp = B::Deparse->new(); my $code = $bdp->coderef2text( \&some_awful_function ); Email::Send->new({ mailer => 'SMTP', mailer_args => [ Host => 'my.example.com' ] })->send(<<'END_MESSAGE'); From: a_kind_person@my.example.com To: mortified_perl_programmer@your.example.com Subject: Here's What Your Code Really Does $code END_MESSAGE

Of course, you might not want to mail deparsed code to people instead of talking to them first -- but you can if you must.

Perl::Critic

After you can read the code in a proper format and understand complex expressions well enough to consider rewriting them, the Perl::Critic toolset can help you identify and avoid well-understood problems in code -- both stylistic and substantial.

The perlcritic utility runs from the command line and can identify the most egregious potential errors in a program or module:

$ perlcritic MyAwfulModule.pm my_nifty_program.pl

There are many command-line options. I like --top which finds the 20 worst violations. Severity levels range from 5 (the default) to 1 (the pickiest); select your preferred range with -n . You can customize P::C policies for your project or organization and you can add other policies as you wish.

P::C policies tend to explain themselves. That is, Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalCan has a brief discussion of why the policy exists and what to do instead. If you take the time to explore various policy violations for a codebase and consider the arguments, you'll learn a lot about writing effective Perl 5 code.

If you want to enforce site policies, the Test::Perl::Critic module is useful. The criticism pragma is another approach worth considering. Gabor Szabo also pointed out the Padre Perl::Critic plugin.

All three of these utilities have options and suggestions and nuances ripe for discovery, but all three of them can provide you an immediate benefit without requiring arduous or tedious customization.

If you want to write better Perl 5 code, start here.