SPUG: Readable, well-written code (was: Best One-Liners and Scripts for UNIX)

Richard Anderson richard at richard-anderson.org
Sun Apr 20 23:32:17 CDT 2003


This use of grep exploits a lesser-known side effect of the function and
bypasses it's main purpose, which is to select elements of a list.  If you
want to apply a transform to every element of a list, Perl provides the map
function:

map { $_ =~ s/(\d+)/$1 * 2/e } @list;

or, preserving the input @list:

@doubled = map { ($x = $_) =~ s/(\d+)/$1 * 2/e;
                               $x;
                            } @list;

When I read Perl code and encounter map, I immediately recognize that the
code is applying a transform to the elements of a list.  This "natural"
style usually takes more lines of code than the "minimal keystrokes" style,
but is less bug-prone and more maintainable.

Richard Anderson
richard at richard-anderson.org
www.richard-anderson.org
----- Original Message -----
From: "Brian Hatch" <spug at ifokr.org>
To: "Richard Anderson" <richard at richard-anderson.org>
Cc: "Bob Hiltner" <bob at hiltners.com>; <spug-list at pm.org>
Sent: Saturday, April 19, 2003 6:54 PM
Subject: Re: SPUG: Readable, well-written code (was: Best One-Liners and
Scripts for UNIX)

> My view is that fluent Perl takes advantage of the Perl idioms that
enhance
> cohesion and readability and avoids Perl idioms that obfuscate for the
sake
> of producing terse code.  An example of this is the grep function.  Any
code
> that uses grep can be rewritten more verbosely as a foreach loop.
However,
> grep enhances readability because when the reader sees grep he knows the
> code is selecting members from a list, whereas the loop is less
immediately
> obvious.  Grep has more cohesion than a loop because its function is
limited
> to selecting members from a list.

Well, not always:

 grep { s/(\d+)/ $1 * 2 /e } @list;

That'll take the first string of numbers in each element of @list
(perhaps lines from a file) and double the number.  It's actually
modifying @list, not just selecting members.

Is more readable than the following?

 for ( @list ) {
  s/(\d+)/ $1 * 2 /e;
 }

Well, the grep one is cleaner to me - less lines to read.  Others may
dissagree, and I wouldn't include it when teaching someone for the
first time how to do that.



--
Brian Hatch                  "I'm thinking .. pastels!"
   Systems and
   Security Engineer
http://www.ifokr.org/bri/

Every message PGP signed




More information about the spug-list mailing list