Preface

This book is designed to help you write better Perl code: in fact, the best Perl code you possibly can. It's a collection of 256 guidelines covering various aspects of the art of coding, including layout, name selection, choice of data and control structures, program decomposition, interface design and implementation, modularity, object orientation, error handling, testing, and debugging. These guidelines have been developed and refined over a programming career spanning 22 years. They're designed to work well together, and to produce code that is clear, robust, efficient, maintainable, and concise.

Mind you, that's not easy to achieve. Conciseness can be the natural enemy of clarity; efficiency the nemesis of maintainability. And armouring code to make it sufficiently robust can undermine clarity, efficiency, conciseness, and maintainability. Sometimes it's a case of: "Choose any one."

This book doesn't try to offer the one true universal and unequivocal set of best practices. There are as many ways of measuring code quality, and as many dimensions in which code can be judged, as there are programmers to make those assessments. Each programmer and each programming team will have their own opinions about the most important and desirable attributes of code.

What this book offers instead is a set of best practices: a set that is coherent, widely applicable, balanced in its aims, and that is based on real-world experience of how code is actually written, rather than on someone's ivory-tower theories on how code ought be created. Most of all, it's a set of practices that actually work, and that many developers around the world are already using. Much like Perl itself, these guidelines are about helping you to get your job done, without getting in the way.

If you're an experienced developer, it's almost certain that you won't like all of the suggestions that follow. You will find some of them unnatural or counterintuitive; others may feel excessively rigid and un-Perlish. Maybe they'll just seem unnecessarily different from the ways you're used to writing software, and from the long-ingrained coding habits you find so comfortable.

Try to put those feelings aside as you read through the advice in this book. Review it as you would any other proposed code enhancement: analyze the arguments that are made for these new practices; ask yourself whether you've ever fallen into the traps they seek to avoid; consider whether the coding techniques suggested here might be worth trying.

Just thinking about these issues—becoming conscious of the way you currently write code—can be of enormous benefit, even if you don't adopt a single one of the recommendations that follow.

Contents of This Book

Chapter 1, Best Practices, explains why it might be worth reassessing your current coding practices. It discusses how coding styles are evolved, and sets out three broad criteria against which any existing or proposed coding practice can be assessed. The chapter also explains why good coding habits matter and suggests how they can be developed.

Chapter 2, Code Layout, tackles the many contentious issues of code layout. It suggests how to set out block delimiters; how to visually distinguish built-ins and keywords from subroutines and variables; where to place operators, terminators, delimiters, and other punctuation; how to improve readability by the consistent use of whitespace; the optimal width for code lines and block indents; how to set out lists of values; and where to break long expressions. It concludes by recommending a convenient tool that automates most of these layout tasks.

Chapter 3, Naming Conventions, presents a series of guidelines that can help you choose more descriptive names for variables, subroutines, and namespaces. It also demonstrates how the various components of a consistent naming scheme can work together to improve the overall maintainability of code, both by making it more readable and by reducing the need for deobfuscatory comments.

Chapter 4, Values and Expressions, provides a simple set of rules that can help you avoid common pitfalls when creating character strings, numbers, and lists. Topics include how to avoid unintended variable interpolation (and non-interpolation), reliable and readable approaches to nonprintable characters, defining constants, avoiding barewords, and taming heredocs, commas, long numbers, and lists.

Chapter 5, Variables, explores a robust approach to using variables. It explains the inherent drawbacks of package or punctuation variables, suggesting safer alternatives where possible, and safer practices where there are no alternatives. The second half of the chapter presents several efficient and maintainable techniques of handling data in arrays and hashes using the "container slicing" mechanism.

Chapter 6, Control Structures, examines Perl's rich variety of control structures, encouraging the use of those that are easier to maintain, less error-prone, or more efficient. The chapter provides a set of simple guidelines for deciding which of for, while, or map is most appropriate for a given task. The effective use of iterator variables is also discussed, including the common case of needing to iterate hash entries by key and value simultaneously.

Chapter 7, Documentation, suggests a series of techniques that can make documenting your code less tedious, and therefore more likely. It advocates a template-based approach to both user and technical documentation, and discusses when, where, and how to write useful and accurate comments.

Chapter 8, Built-in Functions, discusses better ways of using some of Perl's most popular built-in functions, including sort, reverse, scalar, eval, unpack, split, substr, values, select, sleep, map, and grep. It also summarizes the many other useful "non-built-in" builtins provided by two modules from the standard Perl distribution and one from CPAN.

Chapter 9, Subroutines, describes efficient and maintainable ways to write subroutines in Perl, including the use of positional, named, and optional arguments, argument validation and defaults, safe calling and return conventions, predictable return values in various contexts, and why subroutine prototypes and implicit returns should be avoided.

Chapter 10, I/O, explains how to open and close files reliably, when to use line-based input, how to correctly detect interactive applications, the importance of prompting, and how best to provide feedback to users during long non-interactive tasks.

Chapter 11, References, offers advice on demystifying Perl's many dereferencing syntaxes, discusses why symbolic references create more problems than they solve, and recommends ways to prevent cyclic reference chains from causing memory leaks.

Chapter 12, Regular Expressions, presents guidelines for using regular expressions. It recommends the use of extended formatting, suggests a simple but unusual fix for Perl's confusing "single-line" and "multiline" matching modes, warns of the perils of matching whitespace too precisely, shows how to avoid using the error-prone numeric variables, presents a robust approach to building complex regexes that are still maintainable, gives several hints on optimizing slow matches, and concludes by explaining when not to use regular expressions.

Chapter 13, Error Handling, advocates a coherent exception-based approach to error handling, and explains why exceptions are preferable to special return values or flags. It also recommends the use of exception objects, and explores in detail how they can be declared, created, thrown, caught, and handled.

Chapter 14, Command-Line Processing, addresses the design and implementation of command-line interfaces, both for individual programs and for application suites. It recommends several modules that can make your command-line interfaces more consistent and predictable, and at the same time can considerably reduce the effort required to implement those interfaces.

Chapter 15, Objects, and Chapter 16, Class Hierarchies, offer a robust and efficient approach to creating objects and class hierarchies in Perl. This approach provides fully encapsulated objects with no performance penalty, and supports single and multiple inheritance without the usual problems of attribute collision, incomplete initialization, partial destruction, or incorrect method autoloading. Chapter 16 also introduces a new module that allows these robust and efficient classes to be built semi-automatically.

Chapter 17, Modules, looks at non-object-oriented modules, exploring the best ways to create them, design their interfaces, declare and check their version numbers, and refactor existing code into them. This chapter also discusses the many existing modules that are freely available as part of the Perl standard library and on CPAN.

Chapter 18, Testing and Debugging, encourages the use of testing, advocating test-driven design and development using the core Test:: modules. It also offers tips on effective debugging techniques, including a description of various modules and other free tools that can make debugging easier.

Chapter 19, Miscellanea, offers several additional guidelines on miscellaneous topics such as revision control, interfacing to code written in other languages, processing configuration files, text formatting, tied variables, benchmarking and profiling your code, caching techniques, and some general advice on refactoring.

Appendix A, Essential Perl Best Practices, summarizes the 30 most important guidelines in the book in three one-page lists. Appendix B, Perl Best Practices, lists all 256 guidelines, with cross-references to their chapters and locations. Appendix C, Editor Configurations, provides some useful configuration options for the Vim, Vile, Emacs, TextWrangler, and BBEdit text editors. Appendix D, Recommended Modules and Utilities, lists and cross-references the various modules recommended throughout the book, and provides a brief summary of their most useful subroutines. Appendix E offers a short bibliography.

Conventions Used in This Book

The following typographical conventions are used in the text of this book:

Italic

Indicates emphasis, new terms, URLs, email addresses, filenames, paths, and Unix utilities.

Constant-width regular

Indicates commands, variables, attributes, functions, classes, namespaces, methods, modules, values, the contents of files, the output from commands, and code examples that break recommended practices.

Constant-width bold

Indicates commands and other text that should be typed literally by the user, and code examples that demonstrate recommended practices.

Constant-width italic

Indicates text that should be replaced with user-supplied values and comments within code examples.

Code Examples

This book is intended to help you get your job done. In general, you may use the code in this book in your programs and documentation. You do not need to contact O'Reilly for permission unless you're reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O'Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product's documentation does require permission.

O'Reilly appreciates, but does not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: "Perl Best Practices, by Damian Conway. Copyright 2005 O'Reilly Media, Inc., ISBN: 0-596-00173-8".

If you feel that your use of code examples may fall outside fair use or the given permission guidelines, feel free to send a specific request to .

Feedback

Please address comments and questions concerning this book to the publisher:

O'Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
(800) 998-9938 (in the United States or Canada)
(707) 829-0515 (international or local)
(707) 829-0104 (fax)

There is a web page for this book that lists errata, examples, and any additional information. You can access this page at:

http://www.oreilly.com/catalog/perlbp

To comment or ask technical questions about this book, send email to:

For more information about books, conferences, Resource Centers, and the O'Reilly Network, see:

http://www.oreilly.com

Acknowledgments

Every book is the work of a multitude. In writing this one, I have benefitted from the help, advice, and support of many of the most talented people in the Perl community. I would like to express my deepest gratitude:

To Linda Mui, my first editor, for her seemingly limitless patience and continuing faith, which gave me the freedom to eventually find my true subject.

To Nat Torkington, my second editor, for refiring my enthusiasm for writing, and for his extraordinary encouragement, support, and mateship over the past decade.

To Allison Randal and Tatiana Apandi, my third editors, for their grace, composure, understanding, good advice, quiet efficiency, and very practical assistance.

To Sean M. Burke, for his careful technical analysis, invaluable grammatical advice, salient questions, and for an especially brilliant footnote that I sorely wish I could have used.

To Nancy Kotary, for gently improving my writing with her superb copy-editing.

To Larry Wall, for his friendship and wisdom over the past five years, and for teaching me so much in that time, not the least of all: humility.

To Abigail, for bringing a no-nonsense approach to Perl coding and for invaluable advice on many topics—in particular, regular expressions and inside-out objects.

To Nate Bailey, for his unfailing support over the past few years, for helping me craft sentences that make sense the first time, and for his expert second-hand knowledge of sociopathy.

To Hildo Biersma, for his professional perspective on the realities of developing in large team environments, and for considerably more good suggestions than I was able to use in a single book.

To Chris Devers, for consistently better wordings throughout the book, and for saving me from writing an entire extra chapter, when a paragraph turned out to be enough.

To Richard Dice, for marshalling compelling economic arguments to keep the review process on track, and for finding me the perfect business-like operands.

To Stephen Edmonds, for unearthing three very subtle coding errors that would otherwise have passed most annoyingly into print.

To Paul Fenwick, for the much-needed teacher's perspective he brought to the presentation of these ideas, and for duly withholding biscuits when I broke my own guidelines.

To Garrett Goebel, for his extraordinary attention to detail and his remarkable ability to extrapolate from those particulars to excellent general advice.

To Mick Goulish, for enthusiastic encouragement, sound skeptical advice when I was under pressure, and some of the best laughs I've ever had, right when I most needed them.

To Uri Guttman, for seeing things no-one else did, in ways that no-one else could.

To Trey Harris, for so ably representing the expert programmer and thereby inspiring me to find better ways, instead of just easy ways.

To Brand Hilton, for unsurpassed typo correction, his uncanny ability to spot bugs in code samples, and his valiant defence of "unless".

To Steven Lembark, for so many excellent suggestions, and for helping to keep me focused on the needs of real-world developers.

To Andy Lester, for inspiring me with his deep understanding of, and passion for, the best coding practices.

To Greg London, for his insights into the needs of real programmers, and for telling me honestly when the humour didn't work.

To Tim Maher, for his friendship and support over many years, and for occasionally being the essential voice of dissent.

To Bill Odom, for sharing so much of his wisdom and experience, and graciously allowing me to steal so many of his best ideas.

To Jacinta Richardson, for her many excellent suggestions, both grammatical and syntactical, and for her uncompromising opposition to lazy writing.

To Bill Ricker, for his invaluable documenting of guidelines, modules, and versions; his eagle eye for corporate-unfriendly suggestions; and his extraordinary knowledge of computing theory, practice, and history.

To Randal Schwartz, for finding the time to offer feedback on my book despite the heavy demands of concurrently revising two of his own.

To Peter Scott, for sharing his unparalleled experience, knowledge, and wisdom, and for his and Grace's kindness and support in times of sorrow.

To Mike Stok, for his unique perspective on Perl programming, and the many insightful suggestions that flowed from it.

To Tony Stubblebine, for not being afraid to criticize when criticism was warranted, and especially for his sound advice on documentation.

To Andrew Sundstrom, for the unique way he blends the warrior, the philosopher, and the poet in all aspects of his life, including his programming.

To Bennett Todd, whose encouragement and advice I have now relied upon across five years and two books.

To Merijn Broeren, Dave Cross, and Tom Christiansen for their generous offers to help with this book.

To Dave Rolsky, Brian Ingerson, and Eric J. Roode, for being so open to my impertinent suggestions for improving their already excellent modules.

To my fellow Perl Monks: Joe Hourcle, for his detailed and timely help with BBEdit and TextWrangler; John McNamara, Jim Mahoney, Scott Lanning, and Michael Joyce, to whom belongs all credit for the Emacs advice herein; and all the other acolytes, monks, friars, abbots, and saints who helped me put together the editor configuration appendix: artist, barrachois, Fletch, InfiniteLoop, jplindstrom, leriksen, Limbic~Region, runrig, Smylers, and stefp.

To my parents, Sandra and Jim Conway, and my parents-in-law Fred and Corallie Stock, for their unfailing belief in me.

And above all, to my beloved Linda, who is the wellspring of all my inspiration, and the reason for everything I do.

Get Perl Best Practices now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.