Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Perl Best Practices

by simonm (Vicar)
on Jul 22, 2005 at 04:16 UTC ( [id://477093]=bookreview: print w/replies, xml ) Need Help??
Order Perl Best Practices

Item Description: Perl style guidelines and programming techniques from Damian Conway.

Review Synopsis: An entertaining set of suggestions that range from bracket placement to test-driven development.

The much anticipated new book from Damian Conway hit my desk this morning, and I spent a chunk of my evening tearing through it.

It's a wonderful resource, with a web of interconnected and mutually-reinforcing heuristics that reminds me of the better parts of the design patterns literature, although the recommendations are usually at a lower-level of detail then the typical class architecture patterns.

The 256 practices are grouped into logical categories, starting with lower-level syntax and working up to object, module, and project-wide issues. Much of this is familiar ground -- for example, many of the recommendations of perlstyle show up in chapters 2 and 3 -- but for each recommendation Damian includes both the basic, well-organized information that a newcomer would need to learn, as well as a mix of entertaining examples, obscure details, and geeky jokes that will keep the attention of more experienced programmers.

For example, the recommendation to use a four-column indent is accompanied by an ACM journal citation and an amusing anecdote about the competing social pressures that favor 4 over 2 or 8. (And let's not even talk about 3-space indents -- that's totally bizarre.)

There were some stylistic recommendations that I disagreed with, but they were a small minority, and the author makes it clear from the beginning that he's not trying to lay down a system of hard-and-fast rules, but rather expects individual developers to consider these issues in their local context to reach their own conclusions.

Later chapters show sensible ways of handling more complex coding issues, with a reasonable mix of recipes to roll-your-own solution versus pointing the reader towards relevant CPAN modules. Much of the Objects chapter is based on using Damian's Class::Std, and a number of the Perl6::* modules get a plug, but the book generally refrains from just focussing on his own distributions.

Remaining chapters cover documentation, testing, and other larger development issues. The influence of agile methodologies is evident in sections on writing tests first, test automation, and synchronizing code and documentation changes.

All in all, an enjoyable read and a useful reference for my Perl bookshelf.


Replies are listed 'Best First'.
Re: Perl Best Practices
by simonm (Vicar) on Jul 22, 2005 at 04:32 UTC
    For what it's worth, a few minor errata that caught my eye:
    • Page 100, last non-code line: this line references "even()" but all of the earlier mentions said "odd()".
    • Pge 308, first non-code line: "table-drive approach" =~ s/ve /ven /;

    I can't find the Getopt::Clade on CPAN; am I looking in the wrong place?

    Also, on page 151-152, I was disapointed not to find an example of GRT sorting; I know you mention it on page 164, but a roll-your-own example might help popularize this seemingly esoteric technique...

    # Sort by SHA-512 digest of scripts # (optimized with Gutman-Rosler packed default sort) @sorted_scripts = map { substr($_, 64) } sort map { sha512($_) . $_ } @scripts;
      Thanks for the errata. I've passed them on to O'Reilly.

      Getopt::Clade will be on CPAN in August. Unfortunately, my planned release schedule had to be slipped slightly due to a series of family medical emergencies.

      Regarding no GRT example: There were probably two dozen examples of useful-but-not-essential techniques that I had to leave out to keep the book to a "mere" 550 pages. GRT was one of those.

        My sympathies on the medical front; best of luck there.
PBP's .perltidyrc file, was Re: Perl Best Practices
by RMGir (Prior) on Aug 23, 2005 at 11:44 UTC
    Here's the .perltidyrc file PBP recommends; it was left out of the source tarball. Posted with the author's kind permission.

    # PBP .perltidyrc file -l=78 # Max line width is 78 cols -i=4 # Indent level is 4 cols -ci=4 # Continuation indent is 4 cols -st # Output to STDOUT -se # Errors to STDERR -vt=2 # Maximal vertical tightness -cti=0 # No extra indentation for closing brackets -pt=1 # Medium parenthesis tightness -bt=1 # Medium brace tightness -sbt=1 # Medium square bracket tightness -bbt=1 # Medium block brace tightness -nsfs # No space before semicolons -nolq # Don't outdent long quoted strings -wbb="% + - * / x != == >= <= =~ < > | & **= += *= &= <<= &&= -= /= |= + >>= ||= .= %= ^= x=" # Break before all operators

    Any typos are my fault, and not TheDamian's. (Edit: And there are 3 fewer typos than there were, thanks Util!)

    Well, the odd -wbb list is inherited from perltidy's docs, so that one's not mine or his :)

    Edit: Applied update to -wbb pointed out in Re: PBP's .perltidyrc file, was Re: Perl Best Practices. I wonder why !~ was removed?

    Previous -wbb value:

    -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= && += -= /= |= >>= ||= .= %= ^= x="

      perltidy now comes with option -pbp, --perl-best-practices
      -l=78 -i=4 -ci=4 -st -se -vt=2 -cti=0 -pt=1 -bt=1 -sbt=1 -bbt=1 -n +sfs -nolq -wbb="% + - * / x != == >= <= =~ !~ < > | & = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x="
        to know where to place the .perltidyrc file enter perltidy -dpro as reslut you'll get where perltidy is looking to find the config file. if one is found, you'll get the contents.
      The errata corrects -wbb to: -wbb="% + - * / x != == >= <= =~ < > | & **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x="
      -lt , line-up-parantheses is needed for -vt to have effect.
Re: Perl Best Practices
by simonm (Vicar) on Jul 22, 2005 at 04:57 UTC
    As I mentioned, there were a few stylistic guidelines that I don't adhere to; none of them strike me as flat-out wrong, but I've chosen to do things differently.

    For amusement value only, here's a list of things I'd do differently that I noticed while reading through today, mostly from the first few chapters:

    • Use two column indents rather than four.
    • Omit semicolon after the final statement in a block if it is an explicit or implicit return.
    • Cuddle elses and elsifs. (Add a blank line above if the else block forms a paragraph.)
    • When breaking lines for an assignment, put the equal sign after the variable name.
    • When breaking lines in a ternary expression, place the colon under the question mark for simple ternaries, or at the end of each line for cascading ternaries.
    • Always put semicolons at the end of a line, never on a line by itself.
    • It's OK to use implicit returns when a subroutine ends with delegation or calculation of the result.
    • Use two-part version numbers for portability, not three-part version strings.
    • Don't use a hash reference to hold named argument pairs when a regular list of pairs will do; getting an odd-number error at compile time rather than run-time isn't worth the extra punctuation this induces.

    For the more contentious suggestions, Damian does a good job of laying out the various pro and con arguments, so it's easy to see how a development team could use this this text as the basis of their style discussions and end up with a document that says "use the PBP style except for the following 5-10% set of local differences".

      These diffs are about the same we used to have in our coding guidelines in pre-PBP times. We abandoned them in favour of PBP.

      The cuddled else/elsifs and 2-column indentation surely give you a more dense code - you see more "at a glance". But whether it is increasing age or increasing display resolution (increasing dpi as display sizes in notebooks remain quite the same) or both: believe me, having dense perl code on 140dpi+ with 6x13 font and folding on gives you more code "at a glance" you probably can handle.

      What we have learned from PBP is, that it's not perfect. Contextual::Return has its problems with other recommended modules. I'm also missing a clear statement from the Damian about how future-proof the usage of Class::Std really is (in the light of it's flawed maintenance and in light of Moose). Never got any answer to that.

      But other than that, we also have learned, that adhering to some guideline in PBP - even if you do not agree with it - is often the better choice, because the odds you being right and PBP being right are in favour of PBP and, as other people might have thought of other guidelines of their own to be superior to those of PBP, you again end up with a bunch of homebrew codebases.

      Therefore, using Perl::Critic/perlcritic with defaults on -3, trying -2 on own code.

          All Perl:   MT, NLP, NLU

Re: Perl Best Practices
by siracusa (Friar) on Aug 06, 2005 at 17:06 UTC

    I'm not done with the book yet, but the style chapter in particular was a bit like instructions on "how to program like Damian." I guess there's simply no way to cover all stylistic options, and so Damian's choice to present a single, self-consistent style (his own) is understandable. I just wish there'd been more detail in his reasoning. In a few cases, he dismisses alternatives and explains his own choice in a very facile way.

    Time and space restrictions explain that a bit, but even within the bounds of his own recommended style, I wanted to see more exploration of the inherent tensions within his style. For example, his preference for a 4-space indent, non-abbreviated variable names, and very clearly spelled-out subroutine names is slightly at odds with his line length recommendations.

    Similarly, many of the later style rules are consequences of earlier ones. This is fine, and expected, but I wish it was explicitly stated. For example, the choice of K&R braces dictates the continued statement style (e.g., starting continued assignment lines with "=") and the other rules that are meant to disambiguate an indented line from a new scope.

    Overall all, though, the introduction does an excellent job of explaining how to make the most of the style section: even if you disagree with a style guideline, just use it as a means to explore the reasoning behind your own style choice in that area.

    There's one case that (IIRC) he didn't cover, however, when it comes to changing your own style. I have a personal, totally stupid and arbitrary habit of using parens with single-variable "my" statements *only* when I'm pulling off @_ args in a subroutine. (Everywhere else I just do "my $var") I'd like to stop doing it, because it's pointless and inconsistent, but then I'm faced with the problem that all of my new code would suddenly be inconsistent with my old code. And since the habit is not really harmful, I can't bring myself to break the consistency of my own code.

    I imagine this applies to anyone contemplating a style change. So how, do you do it? Do you go back and update all your old code to fit the new style? Or do you just grit your teeth and move forward? Anal-retentive programmers need help in this area! ;)

      my $x = ( 1, 2, 3 ); my ($y) = ( 1, 2, 3 ); say $x; say $y; ... gives different results for the two styles if more than one thing is passed. So I'd stick with my ($x) = ...
Re: Perl Best Practices
by jdhedden (Deacon) on Sep 09, 2005 at 17:22 UTC
    Much of the Objects chapter is based on using Damian's Class::Std
    One problem with Class::Std is that it is not 'thread safe' (and hence not 'fork safe' under Win32).

    While this may be an oversight, it could also be intentional as the book doesn't talk about threads at all.

    xdg presents a mechanism whereby thread-safety can be introduced into an inside-out object model, and I have successfully used it in Math::Random::MT::Auto. Hopefully, TheDamian will incorporate xdg's concept into a future release of Class::Std.

    Remember: There's always one more bug.
Re: Perl Best Practices
by RMGir (Prior) on Aug 22, 2005 at 14:56 UTC
    I bought this over the weekend and started reading it. So far, very nice!! Of course, I've only read thru chapter 2, having read chapter 9 online earlier. :)

    One minor annoyance is that the suggested .pertidyrc file is not included in the source packet from O'Reilly.

    Also, the -wbb option in the .pertidyrc looks a bit... odd. >= is there twice, as is <, unless I'm reading it wrong.

    Ah, looking at the perltidy perldocs, looks like this is just an artifact of copying the perldoc's "break after" list into the "break before" list. So it's an inherited bug, if it's a bug...

Re: Perl Best Practices
by alexm (Chaplain) on Jan 03, 2008 at 00:26 UTC
    It took me a while to read the book because I did it in tiny bits of 1 or 2 tips a day, but it was really insightful and fun. I don't like some tips and love many others, but the whole set is consistent and TheDamian makes his point clear.

    In fact, I haven't been programming in Perl for a few years (I've been making lots of Perl scripts and fixes on existing Perl code as part of my sysadmin job, though). However, as I was discovering things like insideout objects and modules like Class::Std, I felt I needed to spend more time with Perl related stuff again (as in my old days of CPAN Testers), specially OO programming and testing.

    By the way, don't forget to give a try to Perl-Critic, which implements many of the book guidelines. There's also an online version.

      Regarding OO programming, be sure to also have a look at Moose.

Updated notes on modules listed in PBP
by clp (Friar) on Jul 30, 2009 at 01:13 UTC
    See the Perl 5 Wiki for comments on modules recommended in PBP, based on the contributor's opinion of current best practices:
    PBP Module Recommendation Commentary

    The page seems to be actively maintained, and is now at rev 43.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: bookreview [id://477093]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-04-22 22:33 GMT
Find Nodes?
    Voting Booth?

    No recent polls found