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

Brian Hatch spug at ifokr.org
Sun Apr 20 15:19:36 CDT 2003



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

> >Well, the grep one is cleaner to me - less lines to read.  

> My take on this is that just because you *can* use 'grep' in place of 
> 'for' doesn't mean you *should*.
> 
> If the goal is to put it on one line, do this:
> 
>   for (@list) { s/(\d+)/ $1 * 2/e }; # semicolon because it clarifies 
> that I think of this as 1 statement

Hmmn.  Still ugly.

> If the goal is to put the list on the right, use the wacky 
> postconditions that Tim hates (you can leave the
> braces out if you like):
> 
>  { s/(\d+)/ $1 * 2/e } for (@list);

Actually, I like this much better than my grep.  It all falls
back to my "translate perl into english" theory.  Let's see
the translations:

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

     --> substitute 2*the number for all elements of @list
         (only means this if you know 'grep's modification
	 of list elements in perl, which I'll admit is not 
	 frequently the case.)

    for (@list) { s/(\d+)/ $1 * 2/e }; # semicolon because it clarifies 
    --> For all elements of @list, substitute 2* the number
        (again, you need to know that for is magic in that you
	are modifying the array directly too, but this is more
	common knowledge.)

and cart-before-the-horse style:

   { s/(\d+)/ $1 * 2/e } for (@list);
   --> substitute 2* the number for all elements of @list
 

Notice that the grep and the second for loop translate the
same.  The loop more closely resembles how we'd say it.  I
like to say 'what to do', and what' we're doing is modifying
strings to double numbers within them.

> IMO, grep should really be reserved for searching through a list and 
> picking out certain elements. The "side effect" of changing the list is 
> black magic that is unexpected and scary.

I'd argue it's not black magic.  Nothing in 'for' explicitly says
you can modify the list directly.  C coders using perl usually do
the following first:

	for ( $count=0; $count>@list; $count++ ) {
		$list[$count] =~ s/blahblah/
	}


instead of 

	for ( @list ) {
		s/blahblah/
	}

Both for and grep use magic unavailable in other languages.  It's all
a matter of which magic you have forgotten is magical.  To a C
programmer, the list form of 'for' is magic.  To you it's normal.
To me grep is normal.  To many, horrible abuses of 'map' is standard,
to me it still doesn't come as naturally.



--
Brian Hatch                  "Need new body." -- Bree
   Systems and               "No.  Like your body.  Just
   Security Engineer          need to apply appropriate
http://www.ifokr.org/bri/     patches." -- Bri

Every message PGP signed
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.pm.org/pipermail/spug-list/attachments/20030420/4759d55f/attachment.bin


More information about the spug-list mailing list