Beginning Perl Lesson 15


Steps for working on a script someone has given you

You will sometimes get a script from someone else that you can’t get to run successfully or that you need to modify. This can be frustrating, especially if you don’t understand the code the other person has written. Instead of haphazardly trying things in an attempt to get the script to work, you want to organize the process of understanding and fixing or modifying the script you’ve been given.

In this lesson, I provide some steps I use for organizing this process. A lot of these are good ideas to follow when you’re writing your own scripts, too.

Work on a copy of the original script

Make a copy of the original script, and tuck the original script away somewhere safe where you can’t change it. You’ll probably want to go back to it at some point.

Modify only the copy, never the original script.

Get out your copy of Programming Perl

You’ll nearly always come across something you have never seen before. This means you’ll have to look it up in Programming Perl, the Perl reference book. For example, chapter 33 of the 3rd edition of Programming Perl contains all diagnostic messages and their meanings in alphabetical order, which helps when you hit an error you’ve never seen before.

Add comments

As you begin to figure out how the script works, take notes by adding extensive and copious comments to the script.

As you proceed, you will probably find what you think is a bug in the original code. Add a comment that describes the original code and the fix you made. Sometimes what you thought was a bug was not really a bug but something you didn’t fully understand. Other times, the bug really is a bug, and you want to report it (if you can) to the original author of the script.

Save versions of your changes

Every time you make a significant advance, save a copy of that version of the script in a safe place. It’s possible that you’ll screw something up on the next step, at which point it’s good to have something to go back to.

I create versions of scripts by putting numbers in the names. For example, if the original were named, then I would save my versions as,, and so on.

Give variables meaningful names

If you received a script full of variable names like $i, $x, $ll, etc., start renaming the variables as you figure out what they’re used for. You can use the search and replace utility in your editor for this, but be careful so that you change exactly what you want to change.

Add use warnings;

Make Perl work for you. Turn on the warnings and fix them all before going any further.

Add use strict;

Many bugs in scripts are caused by the improper use of variables. This can be controlled with the use strict; pragma, although it’s a lot of work to update a script if the original script does not contain variables declared using my().

Test the script with a small data set

So, someone gave you a script to run and a 10-Mb data file to process with it. The script gets about halfway through the file and dies, but this takes 10 minutes each time you run it.

I have encountered this situation too many times with my own scripts. The solution is to make a small data file that contains the region that causes your script to fail. Then you can run the script on the file in a few seconds. Fix the local problem, then try the script on the full data file again.

Break the code up into manageable units

All too often, you’ll receive a script where everything happens in one big MAIN section with no subroutines. As you begin to figure out what’s going on in the script, see if you can identify portions that could be isolated in a subroutine. The goal is to convert as much code to subroutines as possible, because then your MAIN section gets simpler and simpler.

Experiment with code fragments

You’ll often reach a piece of code you don’t understand. A good approach here is to isolate the problematic code to a separate script and experiment with it using the techniques already described.

For example, if you have a function that you don’t understand, put it in a separate script. In that script, call the function with different types of arguments to see what happens.

Add print() statements

When you’re not sure what’s happening to your variables, add print() statements where you print out the name and the value of the variable. It’s usually best to print to STDERR so you can keep your error messages separate from your output.

Once you have everything straightened out, don’t delete the print() statements but just comment them out. You might want them again later. Once the script is behaving properly, you’re doing your final cleanup of the script, and you don’t think you’ll need the print() statements any more, then you can remove them.

Step through the code with the Perl debugger

If you’re really having trouble debugging the script and using print() statements isn’t helping, then use the Perl debugger. See Programming Perl, 3rd ed., chapter 20 (pp. 506-529) for more information.

The debugger allows you to step through the code line by line. At each step, you can examine the values of variables to see if they’re what you expect.

Consult your local Perl expert

Even the best programmers get stuck. It’s always good to consult your local Perl expert, who can look at your code with a fresh eye and often quickly identify the single character mistake that is causing your script to fail.

Sometimes when you’re stuck, it’s useful just to try to describe what you’re trying to do to someone else. Many times, you’ll be in the middle of the description when you’ll realize what you’re doing wrong.