Perl

We will use the following example, textcount.pl, which computes statistics on text files:

 1   #! /usr/bin/perl
 2
 3   # reads the text file given on the command line, and counts words,
 4   # lines, and paragraphs
 5
 6   open(INFILE,@ARGV[0]);
 7
 8   $line_count = 0;
 9   $word_count = 0;
10   $par_count = 0;
11
12   $now_in_par = 0; # not inside a paragraph right now
13
14   while ($line = <INFILE>) {
15      $line_count++;
16      if ($line ne "\n") {
17         if ($now_in_par == 0) {
18            $par_count++;
19            $now_in_par = 1;
20         }
21         @words_on_this_line = split(" ",$line);
22         $word_count += scalar(@words_on_this_line);
23      }
24      else {
25         $now_in_par = 0;
26      }
27   }
28
29   print "$word_count $line_count $par_count\n";

The program counts the number of words, lines, and paragraphs in the text file specified on the command line. As a test case, let's use the file test.txt shown below (you may recognize this as similar to text from Chapter 1):

In this chapter we set out some basic principles of debugging, both
general and also with regard to the GDB and DDD debuggers. At least one
of our ''rules'' will be formal in nature, The Fundamental Principle of
Debugging.

Beginners should of course read this chapter carefully, since the
material here will be used throughout the remainder of the book.

Professionals may be tempted to skip the chapter. We suggest, though,
that they at least skim through it. Many professionals will find at
least some new material, and in any case it is important that all
readers begin with a common background.

There is one blank line at the top, two after Debugging and one before Professionals. The output from running our Perl code on this file should be as shown below:

$ perl textcount.pl test.txt
102 14 3

Now, suppose we had forgotten the else clause:

else  {
   $now_in_par = 0;
}
\end{Code}

The output would then be

\begin{Code}
$ perl textcount.pl test.txt
102 14 1

The word and line counts are correct, but the paragraph count is wrong.

Perl has its own built-in debugger, which is invoked via the -d option on the command line:

$ perl -d myprog.pl

One drawback of the built-in debugger is that it does not have a GUI, but that can be remedied by running the debugger through DDD. Let's see how we could use DDD to find the bug. Invoke DDD by typing

$ ddd textcount.pl

DDD automatically notices that this is a Perl script, invokes the Perl debugger, and sets the green "you are here" arrow at the first executable line of code.

Now we specify the command-line argument, test.txt, by clicking Program | Run and filling in the Run with Arguments section of the pop-up window, as seen in Figure 8-2. (You may get a message in the DDD Console along the lines of "… do not know how to create a new TTY …" Just ignore it.) Alternatively, we could set the argument "manually" by simply typing the Perl debugger command

@ARGV[0] = "test.txt"

in the DDD Console.

Since the error is in the paragraph count, let's see what happens when the program reaches the end of the first paragraph. This will occur right after the condition

$words_on_this_line[0] eq "Debugging."

becomes true. Let's put a breakpoint near the beginning of the while loop. We do this in exactly the same manner as we have seen for C/C++ programs, by right-clicking the line and choosing Set Breakpoint.

We should also impose the above condition on this breakpoint. Again, click Source | Breakpoints, making sure the given breakpoint is highlighted in the Breakpoints and Watchpoints pop-up window, and then we click the Props icon. Then we fill in the desired condition. See Figure 8-3.

We then select Program | Run. (We do not choose Run Again, as this seems to take one into the Perl internals.) We move the mouse pointer to an instance of the variable $words_on_this_line, and DDD's usual yellow box pops up displaying the value of that variable. Thus we confirm that the breakpoint condition holds, as it should. See Figure 8-4.

After pressing Next a few times to skip over the blank lines in the text file, you'll notice that we also skip over the line

$par_count++;

which was supposed to increment the paragraph count. Working backwards, we see that this was caused by the variable $now_in_par being 0, and by following up on this observation we soon realize how to repair the bug.

A breakpoint can also be disabled, enabled, or deleted in DDD by selecting Source | Breakpoints, highlighting the breakpoint, and then clicking the desired choice.

If you change the source file, you have to notify DDD to update itself by selecting File | Restart.

To develop Perl code in Eclipse, you'll need the PadWalker Perl package, which you can downloaded from CPAN, and the EPIC Eclipse plug-in for Perl.

Again, the basic operations are the same as what we described before for C/C++, but note the following:

Figure 8-5 show a typical Perl debug screen. Note that we've added the my keyword to the global variables.