Sunday, July 24, 2005

Rich Resource for Elegant Code: Perl Best Practices by Damian Conways

WAY TO GO

Program code, whether it's written in Perl or another language, can range from lucid to occult, depending on how intelligently the programmer documents it. But in Perl programming, according to Damian Conways' Perl Best Practices, lucid code means much more than judicious commenting. From the arcane (not padding values with leading zeroes to make them line up) to the esoteric (factoring out common affixes from alternations to avoid endless re-matching), these practices can help lift your Perl code from spaghetti to elegance.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
—Introduction to Perl Best Practices

Conway begins with a discussion of why programming style matters, and why it's important to make your style consistent and accessible. In this, he cites three goals for "best" code: robustness, efficiency and maintainability; and he gives plenty of examples to show the merit of each. He quotes Larry Wall, the originator of Perl, "We do not all have to write like Faulkner, or program like Dijkstra. I will gladly tell people what my programming style is, and I will even tell them where I think their own style is unclear or makes me jump through mental hoops. But I do this as a fellow programmer, not as the Perl god..."

Having cited the Perl god in support of his effort, Conway launches right into the practices themselves. He begins with "Code Layout" and "Naming Conventions" to show how top-down management of code can make the process easier, and open later stages of a programming project to lucidity. His simple suggestions (Never place two statements on the same line. Abbreviate only when the meaning remains unambiguous) are logical, and need little justification when each is taken alone. Together, these two chapters lay easy-to-understand foundations for Conway's dive into the abstrusities of Perl.

Quoting Arthur Norman ("Data is semi-animate... sort of like programmers."), Conway next discusses "Values and Expressions," where he points out some of the pitfalls of applying any style-law across the board without considering it fully. For example, he notes, blindly following a code-layout rule to align things vertically doesn't make sense if you add leading zeros to a values table to make them align. Perl takes the leading zeros to denote octal numbers, and your carefully-entered values become something quite different than you intended.

Chapter 5, "Variables," explores a robust (read: bug-resistant) way to code variables, whether you need to use package or punctuation variables, localization, or hash and array slicing. Conway includes plenty of code examples (for both good and bad code) to illustrate what he means. With the next chapter, "Control Structures," the book gets into more-obvious programming choices, exploring loops and if-else statements with an eye to making good decisions early in the programming process. ("Reject as many iterations as possible, as early as possible.")

It isn't until Chapter 7 that Conway addresses "Documentation," often the launching-point of other such texts. From such choices as what to put in the POD (Plain Old Documentation, the user text) and what to reserve for technical readers, Conway procedes to offer excellent suggestions to make documentation easier. Alluding to the pig's singing teacher, for example, he advises, "...don't put implementation details in the user documentation. It wastes your time, and annoys the user."

From there, Conway goes into the inner capabilities of Perl from the coder's perspective: Chapter 8 discusses the "Built-In Functions" of standard Perl code and those available from CPAN; Chapter 9 covers "Subroutines" with an eye to using them in efficient and maintainable ways; and Chapter 10 tells how to handle file "I/O" effectively. The same simple tips enliven the next chapters and explain pitfalls that lie in wait for the unwary: "References" (Chapter 11) shows how to avoid problems with symbolic and cyclic references that could lead to "memory leaks"; Chapter 12 gives guidelines for using "Regular Expressions," including the the issue of factoring alternations.
Any alternation of subpatterns can be expensive... Every alternative that has to be tried requires the regex engine to backtrack up the string and re-examine the same sequence of characters it has just rejected... nested backtracking can easily produce an exponential increase in the time the complex match requires.

The next five chapters cover programmer-designed interfaces and displays. "Error-Handling" (Chapter 13) explains why the way your code reacts to exceptions is an important part of the overall design; Chapter 14 discusses how to design a useful interface as a "Command-Line Processor". Chapters 15 and 16 cover how to create robust and efficient "Objects" and "Class Heirarchies" with little to no performance penalties, while Chapter 17 examines the most efficient ways to use object-oriented "Modules," including not only standard Perl modules, but also those found on CPAN.

In Chapter 18, Conway winds up the structured suggestions with the sine qua non for creating robust code, "Testing." Entire books have been written about the need to test code, and this chapter condenses the most useful tips into helpful guidelines. From "Write the test case first" ("probably the single best practice in all of software development..."), to "Write test cases that fail" ("Testing is not actually about ensuring correctness, it's about discovering mistakes..."), to "Never assume that a warning-free compilation implies correctness...", Conway's tips provide a roadmap for effectively testing your code.

After a chapter on "Miscellaneous" items, the book concludes by tying together the tips in two appendices. Appendix A excerpts the "top ten" techniques for optimizing your Perl coding in three categories: Essential Development Practices, Essential Coding Practices, and Essential Module Practices. Each "essential" is connected to the chapter where examples will be found. In Appendix B, every tip statement is listed in order, along with the item title associated with it in the book. This makes it easy to track back through the text. ("Where did I see that example about multi-contextual return values?")

Appendic C covers how to set up the optimum configuration for common editors like vim, vile, BBEdit and TextWrangler. The Appendix D lists recommended modules, subroutines, and utilities that will make the coding and testing process simpler, and the final appendix provides a bibliography. With the rich index, these "utilities" make the manual work as an excellent reference, as well as an initial guide.

As a beginning Perl programmer, I need all the help I can get. Damian Conways' Perl Best Practices is one of the most useful resources I've yet encountered in my quest to create elegant code.
0596001738,0596100922,0596004567,0596101058,0596000278,1565926994,1565924193


Please join us at BlogCritics to comment on this review.