SPUG:Best One-Liners and Scripts for UNIX

SPUG-list-owner tim at consultix-inc.com
Sun Apr 20 13:06:20 CDT 2003


On Sat, Apr 19, 2003 at 01:22:59PM -0700, Bob Hiltner wrote:

> Seeing all the one-liners (not this post particularly) brings to
> mind one of the great things about PERL. You don't need code
> obfuscation utilities for IP protection. It's done automatically at
> the source code level! ;^) What's the other way to say it? Write
> Once, Read Never?

Although I admit that Perl can be written inscrutably, to a degree
that most other languages can only *dream* about, IMHO the
majority of the posts to our list on this subject have been fairly
lucid, rather than obscure.

The principal subtlety has been the usual one, where there's lots
happening with regard to $_, although it never actually makes an
appearance.  That's perfectly acceptable, IMHO, in small scripts
like these where the global nature of that variable isn't likely
to lead to "unintended clobberation".  (After all, we're not aiming
to make these programs readable by Cobol programmers!)

There have been a few rather dense and terse one-liners featuring
somewhat mysterious map/grep manipulations, however, that I had
to stare at for too long to comprehend; but that's one of the
trade-offs programmers are willing to make sometimes to force some
significant data processing into one-line versions, which might
never be intended for other eyes.

I was glad to see that most postings also refrained from needless
stylistic variations, like the "backwards" phrasings that some
cherish but teachers like myself tend to eschew, such as "print
if $true".

I certainly don't want to start a religious war on this issue, but
it triples the amount of Perl knowledge one must have to process
this stuff, given that the syntax is not just backwards, it's
totally different from the more prosaic and classical approach:
"if ($true) { print }".  Why is this triply rather than doubly complex?
Because if you decide to add something new to the backwards form,
you have to change the syntax to get a block in there, using
do {} or some other creative solution, as in
	do { print; $i++ } if $true;

And don't get me started on the infinitely lame do-while, which can't even
process flow-control requests on its own without a while(){} wrapper to
'proxy' them.

This is the kind of needless additional complexity that I like
to avoid in my work, and my teaching, and that I discarded from
the language when crafting my "Minimal Perl" dialect (coming to a
bookstore near you this summer!).
 
> On a more serious note... that is one of the things that does make me shy
> away from getting into perl in a serious way... too much magic.  This stuff
> that (perhaps) makes sense to the initiated and the high priests is like
> reading binaries to the casual perler.   

I always wonder what people are specifically talking about when
they see "magic" in the kind of code we've been slinging around here.

Is it magic that perl "-n" gives you a free loop?  If so, is it also
magic that "grep -i" ignores case, or "sed 's///g'" does multiple
substitutions?  Not in my book.  There's plenty of "magical"
(surprising and automatic) activity in Perl, but I don't recall
seeing any of it here.

There was one code sample posted early on in this thread that spent
about 7 lines to implement the generic input reading loop that -n
gives you for free; I followed up with a one-line version of that
part, that showed it for what it really was, a Perl implementation
of a simple sed editing command.  Is this magic?  Not in my book
(if you'll pardon the pun); instead, it's just a worthwhile
simplification that lets the reader focus on the data processing
task, instead of having to wade through boilerplate infrastructure
that has already been factored out by The Larry and memorialized in
"-n".

As a case of what most of us might call "magic" in Perl, but
I'd perhaps call "tomfoolery" instead, "eof()" and "eof" do very
different things, as do "use Abc()" and "use Abc".  This is the
kind of thing that I personally find very reprehensible in Perl,
because programmers are led by other aspects of the language to
believe that parentheses around argument lists are optional, and
without any intrinsic meaning of their own.  That's "bad magic", IMHO.

And of course there's "autovivification" as another example of
magic, but in Perl's defense I'd say it usually does what you meant
it to anyway, and in any case you can skirt the issue by
initializing on your own the objects it would create.

> I've been doing more .Net stuff for a while, and I feel the
> understandability of perl quickly slipping away when I (try to) read
> stuff like this. I don't see the same issues at all when I get away
> from, say, C for a while. Is that just the idioms of the language?

Raw C provides no shortcuts, so one must always code all the routine
data processing minutiae (unless you extend the language with
macros) that we're allowed to invoke through invocation options
like -n in Perl.  Sure, that makes it more readable, in the sense
that every tiny detail is spelled out, but IMHO that also makes it
less comprehendible, because it's too easy to miss the view of the
trees for that of the forest.
 
> It might just be me. I tend to have the same problem with regexes,
> which I think are the coolest thing going. If you don't use em for a
> while, it's a bit of retraining each time. It'd be nice to have that
> kind of power with some better readability.
> 
>     -Bob

I know what you mean about regexes, and caught myself just yesterday
staring at an extremely simple expression that wouldn't match the
comments it was supposed to:

	s/^(.*)\b(#.*)$/

The problem of course is that \b does not mean a "word boundary"
in any English language sense of "word", so this pattern would not
match " # comment" but instead only strings like "ABC# comment"
(where the C qualifies as a character of the opposite kind to #
with respect to the [a-zA-Z_] set).  Personally, I find regexes
harder to debug than anything else in Perl, and I would very much
like to get access to a debugger that doesn't require a GUI to work
(I know there are Perl IDE's out there, but I'm a VI in an xterm
kind of guy, in part due to my set of "vi-abbreviations"
that prevent me from typing too much).

But it's not just you, there are lots of people who don't like the
way Perl programs look. And I was one of them, in my early days with
the language.  In my case, after realizing that some Perl features
were really shortcuts for processing idioms I knew from other parts
of UNIX made it all click for me (like -a for Awkish behavior,
-i for sed-ish, but including the all-important file-altering
capability that sed left out, etc.) 

For other aspects of Perl coding, like backwards conditionals and
arcane uses of map, I just include the parts I like and avoid the
others, and I'm happy with the custom Perl dialect I use.  And I
know from teaching it to UNIX programmers for many years that others
with my kind of background are happy with it too.

Perl's a huge language, with more diversity of expression than any
of its peers, so everybody should be able to find a dialect within
it that suits them. 

I can generally tell from reading the programs of my students what
languages they've learned earlier.

For example, using

	for ($i=0; $i<@ARGV; $i++){ print "$ARGV[$i]\n";}

to print the script's arguments identifies a C, C++, or Java
programmer (all from the C-school), who's reluctant to trust Perl
not to run off the end of the array and crash, and

	foreach (@ARGV){ print "$_\n";}

is more characteristic of shell programmers, who are perfectly happy to
trust Perl to do the right thing.

Happy Easter, everybody!  Eat plenty of chocolate. . .

-Tim
*------------------------------------------------------------*
|  Tim Maher (206) 781-UNIX  (866) DOC-PERL  (866) DOC-UNIX  |
|  CEO, JAWCAR ("Just Another White Camel Award Recipient")  |
|  tim at Consultix-Inc.Com  TeachMeUnix.Com  TeachMePerl.Com   |
*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*
|  Watch for my  Book: "Minimal Perl for Shell Programmers"  |
*------------------------------------------------------------*



More information about the spug-list mailing list