Debugging Perl: Troubleshooting for Programmers
When I first received a copy of Martin Brown's Debugging Perl: Troubleshooting for Programmers from Linux Journal HQ, my initial reaction was: how could anybody possibly write an entire book on debugging Perl? A chapter or two I could imagine, but an entire book?! Well, write an entire book is what Martin Brown has managed to do, but it is not an entire book on debugging. The author has thrown in quite a bit of additional material to pad things out, but more on this later.
Let's begin by getting the statistics out of the way. This book has six parts, 14 chapters, an appendix and runs to over 400 pages (excluding the index). I'll now describe the content, part-by-part.
After a short introduction (called "Introduction"), Part I, "Introduction to Perl Debugging", contains a single chapter called (rather confusingly) "Introduction". (Umm...two introductions? This should have been my first clue about the problems to come). This short chapter introduces debugging to the reader and describes the different types of bug that can inflict a Perl program. The author also introduces the idea that, when it comes to dealing with bugs, planned prevention is often better than the cure. He suggests that better design, a good code-editor, improved code formatting and appropriate comments can go a long way toward not introducing bugs in the first place. This is a noble idea. However, most Perl programmers will be drawn to this book precisely because they have bugs in their code. To be told that it would have been better not to introduce the bugs in the first place really serves no purpose (other than to annoy the reader).
Part II, "Perl Logic and Syntax", has five chapters which takes the author's idea of "prevention is better than cure" further and identifies the common things that can go wrong when writing a Perl program. Chapter 2, "Basic Perl Parsing Rules and Traps", talks about the process that Perl (the interpreter) goes through when running a Perl program. The treatment of how Perl works internally is quite readable, much more so that the perlguts manpage. However, I had to question its inclusion, as it is typically only of interest to programmers working on the Perl source code. With the discussion of Perl internals out of the way, the Perl syntax and parsing rules are described with reference to the common mistakes that occur when they are poorly understood. Most Perl programmers will find much of this material familiar.
Chapter 3 contains a list of common variable errors (or "traps" to use the author's terminology). Again, a lot of this material will be familiar to Perl programmers, especially if they have read the latest edition of Programming Perl (O'Reilly, 2000). Chapter 4 covers statement and function traps in much the same manner as variables in Chapter 3. There's really nothing too new here, either, and Table 4.1 (beginning on page 79) is a rehash and summary of the "Functions" chapter from Programming Perl.
Chapter 5, "Program Design", will only be of interest to the Perl newcomer. Here, the author presents his views on how to best design subroutines, modules and objects. A bunch of "time saving tricks" are also described in this chapter. This material is generally okay, but, what is it doing in a book on debugging? In my opinion, the questionable material includes the discussion of using prototypes when designing Perl subroutines. The author takes the view that prototypes are a good thing. However, the jury is still out within the Perl community, as prototypes, if used incorrectly, are sometimes more trouble than they're worth. Some notable Perl programmers--Tom Christiansen, for instance--have come out against the idea of prototypes and are on record stating such. (See http://www.perl.com/pub/language/misc/fmproto.html for a discussion paper on this topic.) Suggesting prototypes should always be used, as the author does in this chapter, is poor advice.
The final chapter in this part, "Language/Platform Migration Guide", begins by listing the mistakes users of other programming languages make when moving to Perl. But, except for the inclusion of a collection of "Python Traps", this material is a reworking of the perltrap manpage. It can also be found in Chapter 24 of Programming Perl, for that matter. The second part of this chapter describes the problems that can surface when porting Perl scripts from one platform to another. As with most of the other material in this part of the book, this has been well-documented elsewhere.
Part III entitled "Error Trapping", contains four chapters. Chapter 7, "Basic Error Trapping", covers the mechanisms used to trap and react to errors within a running Perl program. These techniques will be familiar to every Perl programmer. When talking about the warn and die in-built subroutines, the author states that the subroutines are "in essence...identical", which is wrong. The discussion of the carp, cluck, croak and confess subroutines is equally flawed and confusing. At the end of the chapter, example code for reporting errors within Tk and web applications is presented. The code looks impressive enough (especially the Tk code), but it seems out-of-place and did not come with adequate explanation. What, for instance, does the parse_template subroutine listed on page 159 do? It looks critical to the code, as it is invoked three times, but does not receive mention in the accompanying text. Chapter 8, "Using Pragmas and Warnings", is a rehash of Chapter 31 from Programming Perl.
Finally, after 185 pages, the author gets around to the business of debugging Perl code. I was hoping the chapters on debugging would be this books salvation. What I expected to see was a collection of error-riddled Perl programs which the author would then use to demonstrate various debugging techniques. Alas, it wasn't to be.
Chapter 9, "Manual Debugging Techniques", starts out by describing the tried-and-true technique of embedding "print" statements in code to help uncover bugs. Other material covers the use of the caller and eval in-built subroutines, as well as the method of using signals and log files to store information about a running program. This isn't really debugging (in my mind, anyway), but, when used after-the-fact, the output and logs may hint at where a problem lies.
Chapter 10, "The Perl Debuggers", presents the standard command-line debugger (which comes with Perl) as well as the Windows-hosted ActiveState debugger. I can't comment on the ActiveState material, but the Perl debugger is documented in the perldebug manpage, and the author's treatment adds nothing new to the topic. To makes matters worse, the sample output from the debugger refers to a program introduced in the last chapter, only the author neglects to mention this, which left me (initially) a little confused as to how the sample output was being generated. When I did figure out what was going on, I was amazed to see that the author was debugging a functioning program that contained no bugs! The latter part of the chapter briefly surveys the extra debugging information that can be generated by the Perl interpreter, assuming it was built with the debugging flag. In keeping with the general theme, a lot of this material can be found in the Perl manpages.
Part IV, "Optimizing Your Code", contains two chapters: "Manual Optimization" and "Automatic Optimization". The manual chapter presents a small collection of better ways to do things. Most of this material is available elsewhere. The automatic chapter documents the Perl Profiler as well as a collection of Perl compilers and backends. Now, if someone can explain to me how using the optimization techniques described in these two chapters can help with the process of debugging, I will gladly accept their inclusion in this book. As it is, (and being a "if it ain't broke, don't fix it" programmer), I don't think a book on debugging should mention optimization at all. Others may not agree with me.
Part V, "Testing Your Code", contains chapters entitled "Testing Methods" and "Breaking Your Code". The chapter on testing methods should have been placed much earlier in the book, for how else can programmers determine if there are bugs in their software (prior to delivery to a user) if not through the development of a good test suite? Unfortunately, this important topic is only afforded a light treatment, which is a shame. The code breaking chapter again had me scratching my head in wonder as to the inclusion of such material in this book. As I turned the final page, I let out a long frustrated sigh of relief. Except for the appendix, I was done.
The single appendix fills the final part of the book (VI). The author presents a long list of all the error messages produced by Perl 5.6.0, together with some brief commentary. The entire list runs to over 60 pages, the same 60 pages that appear at the end of Programming Perl. A few words are changed here and there, and the layout and presentation is slightly different, but it is the same content! This material is also available in the perldiag manpage, which is where, I suspect, the authors of Programming Perl got their copy. The difference is that the Programming Perl authors probably wrote the on-line documentation (or had a hand in writing it). Mr. Brown should have credited his source.
I was disappointed to uncover a number of typos and errors all the way through Debugging Perl: Troubleshooting for Programmers. For example, at the very bottom of page 66, when suggesting a technique for dealing with nested structures, the author presents the following line of Perl code "for clarity"
print join(', ',@{list}$hash{)
As any Perl programmer will tell you, this is illegal. Granted, mistakes can be made, but this is a book on debugging...at the very least, readers expect the code presented to work! One of the most embarrassing goofs appears when the author covers traps for C programmers. When describing what's in C but not in Perl, near the bottom of page 122 you will find: "There is no switch statement in C, although you can emulate it in a number of different ways in Perl" ... which will be news to millions of C programmers everywhere! A few pages later, he refers to the "perldelta main page", as opposed to "manpage". These errors easily make it past a spelling checker (or copy editor), but they shouldn't make it past the technical editor, nor the author for that matter. I hate to say it (but I can't resist): Debugging Perl: Troubleshooting for Programmers needs itself to be debugged. There really is no excuse for this many errors and typos. It may well be that the author succumbed to the pressure of rushing to fill a perceived gap in the Perl book marketplace. Sadly, the overall quality of the entire production has suffered.
So, would I recommend Debugging Perl: Troubleshooting for Programmers to the Perl community? Well...there is a small amount of good material here, but there's also a lot of material included that is available and accessible elsewhere. Experienced Perl programmers (who are a large part of this book's target audience) should save their 40 bucks and (maybe) wait for a much-reworked second edition, if there ever is one. Newcomers to Perl may well get more from this book, but need to be wary, as the errors in the text may cause more harm than good, and--at the very least--confuse the newcomer.
I have no doubt that Martin Brown knows his Perl. He is the author of a number of other books on the language. It is just a pity that what could have been an essential addition to every Perl programmer's library has been, well, botched.
Paul Barry (paul.barry@itcarlow.ie) lectures on computer networking at The Institute of Technology, Carlow, in Ireland (http://www.itcarlow.ie). He is the author of Programming the Network with Perl, which will be published by John Wiley & Sons.
email: ljeditors@ssc.com