Ïðèãëàøàåì ïîñåòèòü
Ãðèí (grin.lit-info.ru)

4.3 Style

Previous Table of Contents Next

4.3 Style

In [SCOTT01], Ed Wright and I said, "The only believable comment to make about style is that you should have one." I'll go further than that here. Just as in clothing, having a consistent style doesn't necessarily mean other people won't laugh at you. So, to prevent you from accidentally picking a coding style that's equivalent to a 1970s-era pool hustler, here is a suggested style that's rather more conservative.

Of course, some people intentionally dress like pool sharks and may take umbrage at this disparagement of their sartorial tastes. By all means stick with an idiosyncratic style if you've arrived at it through conscious decision and you can live with the consequences. This section is for everyone else. Like many parts of this book, it incorporates a certain amount of personal taste that is one of a number of ways of getting a job done well; I'm not holding it up as the "One True Way."

You can find comments on style in the perlstyle documentation page that comes with Perl, parts of which are reflected here.

4.3.1 Layout

The best thing you can do for the layout of your program is to indent it properly. I continue to be amazed by how many people in my classes write programs with no indentation whatsoever, as though there were a price on the head of anyone using white space. My own tendencies are so ingrained in the other direction that I have to fight the urge to indent my one-liners! No matter how brief or short-lived the program, you're doing everyone a favor by indenting it from the beginning. Many editors make this process painless.

perlstyle recommends a four-column indent; I use two columns because it's enough for my eyes to recognize the block structure and I don't want deeply nested blocks crowding the right margin. Some people favor an eight-column indent by virtue of using the tab character for each indentation level, and I personally find this far too large. They sometimes claim that they merely need to set the tab stops in their editors to four columns to get good-looking indentation, but this forces maintenance programmers to fiddle with their editor configuration, something many programmers are so possessive of that you might as well ask them to stop breathing.

When it comes to brace styles for code blocks, programmers break out into confrontations that make Jonathan Swift's big-endian/little-endian battles ([SWIFT47]) look like Amish barn-raisings. I prefer a style called the BSD/Allman style:


sub read_dicts

{

  my $dictref = shift;

  my @path = split /:/, $ENV{DICTPATH} || "$ENV{HOME}:.";

  local @ARGV = grep -e, ($DEFDICT, map "$_/.dict" => @path);

  while (<>)

  {

   # Assume the line contains a single word

   chomp;

   $dictref->{$_}++;

  }

}

whereas most of the Perl distribution uses the so-called K&R (Kernighan and Ritchie) style:


sub read_dicts {

  my $dictref = shift;

  my @path = split /:/, $ENV{DICTPATH} || "$ENV{HOME}:.";

  local @ARGV = grep -e, ($DEFDICT, map "$_/.dict" => @path);

  while (<>) {

    # Assume the line contains a single word

    chomp;

    $dictref->{$_}++;

  }

}

which saves a line per block but makes it harder—to this author—to see where the block begins, particularly because a continuation line may be indented. For example:


update($controller->connection, $record[$cur_count]->ticket,

       $form_inputs->{params});

might force you to check the end of the first line to make sure it wasn't ending with a brace. Another example:


if (($best_count == 1 &&   $self->{single_match})

 || ($best_count >  0 && ! $self->{single_match})) {

    $found_match = 1;

}

which—even with a four-column indentation—looks more confusing to me than


if (($best_count == 1 &&   $self->{single_match})

 || ($best_count >  0 && ! $self->{single_match}))

{

  $found_match = 1;

}

with only a two-column indentation. (Although to be fair, some K&R adherents suggest this case is worth an exception.) See also how the continuation line was given a nonstandard indentation so the parallel clauses could line up nicely. Don't underestimate the value of using white space to prettify code in this way.[4]

[4] After some conversation with K&R adherents, I am starting to suspect that the difference between them and the BSD/Allman camp is that they tend to look at the ends of lines for semantic clues, whereas we look at the beginnings. Experiment with both styles and see which one you find more appealing.

Although there are at least two ways of conditionally executing a single statement without putting it in an if block, if that statement is long enough to overflow the line, using a block for it may be clearer than the other approaches (because it looks like multiple statements, even if it isn't):


if (@problems)

{

    error("We found the following problems:\n"

          . (join "\n" => @problems)

         );

}

The non-block ways of conditional statement execution are:

  • condition and statement

    For example:

    
    /(banana|apple|pear)/ and push @fruit, $1;
    
    
  • statement if condition

    For example:

    
    warn "Reached line $." if $verbose;
    
    

Code should be as pleasant to look at as you can possibly make it without ornateness that's fragile with respect to modifications—you don't want to shy away from making necessary changes just because they would destroy a beautiful piece of formatting.

    Previous Table of Contents Next