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:
When creating a project, choose Perl Project.
Use Navigator as your navigator view.
There is no build phase, as Perl does not produce byte code.
In the Debug perspective, the values of the variables are accessible only in the Variables view, not by mouse action in the source code view, and only for local variables.
You'll need to use the Perl my
keyword in the first instance of each variable in your source code in order to see the global variables (this is where the PadWalker package comes in).
Figure 8-5 show a typical Perl debug screen. Note that we've added the my
keyword to the global variables.