Subject: How to write legible perl code: Summary - Take 2

From: Shlomi Fish <[email-masked]>
Date: Mon, 13 Aug 2001 13:42:00 +0300 (EEST)

I am posting this summary again here, due to the fact the previous thread
diverted to something else. (<irony>thanks, OmerZ!</irony>).

Now, I want to discuss how to write legible perl code in the 50-lines
blocks level. If anybody has any suggestions, corrections, notes, or
whatever regarding this issue, please post them here.

Regards,

	Shlomi Fish

<<<<< Summary starts here >>>>>

Forward:
--------

* Perl was designed so that quick and dirty code could be easily written.

* If, however, the code needs to be maintainable, some common perl practices
should be avoided.

* Perl beutifiers can help in presenting the code well, but they still
don't usually re-write badly-written code for you.

* Some of those techniques can be applied after an initial version of the
code has been written. Others should better be thought about from the start.

Making your code look understandable:
---------------------------

1. Indent - even within the expressions.

Splitting statements is your friend:
------------------------------------

* Try to split complex statements (especially perl pipeline ones) into
several statements if possible.

If not possible - encapsulate inside inner closures and/or indent to show
the structure of the statement.

* Pass a s///e expression that becomes to complex into a function or a
closure.

Good (IMHO) Perl Style:
-----------------------

* Avoid using "$cond && print hello;" or "$cond and print hello" forms. It's
confusing for people who are used to other languages. Use if or unless
instead.

* The $_ variable - do not use it unless you have to - like in map or grep.
In the latter it is sometimes advisable to assign its value to a "my"
variable with a more meaningful name.

* use English;

9. Avoid using $var = eval { }, $var = do { }. Prefer the following form
my ($var);
{
    my $local_var1;
    my @local_array2;

    $var = [ expression or closure ]
}

Reason: people scan a code while having to remember that it is eventually
assigned to a variable.

* Always use return at the end of the function.

Writing Legibile Algorithms:
----------------------------

* splice - if can be replaced with a different functions (push, pop, a comma)
- should be. If not - better be put on its own statement.

* Put your ifs and whiles before the conditional block, not after the
statement.

* Emulating a do-while loop:
    a. with a closure.

        my $action = sub {
                [
                    Loop's body.
        	]
            };

        $action->();
        while($cond)
        {
            $action->();
        }

        Has the problem of an extra overhead.

    b. using a $perform_first_iter boolean.
        my $perform_first_iter = 1;
        while ($perform_first_iter || ( [ rest of condition ] ) )
        {
            $perform_first_iter = 0;
        }

    c. A goto-into the loop:
        goto after_condition;
        while ( [ condition expression ])
        {
        	after_condition:

        }
       Has the problem of a possible namespace collition if more than one
       such construct exists inside a function.

General Programming Methodologies (not specific to perl)
--------------------------------------------------------

* Comment your code with numerous and helpful comments.

* Use meaningful names for the variables.

* Write an architecture document if applicable.

----------------------------------------------------------------------
Shlomi Fish        [email-masked]
Home Page:         http://t2.technion.ac.il/~shlomif/
Home E-mail:       [email-masked]

A more experienced programmer does not make less bugs. He just realizes
what went wrong more quickly.

---

From: Omer Zak <[email-masked]>
Date: Mon, 13 Aug 2001 13:56:39 +0300 (EET DST)

> whatever regarding this issue, please post them here.

[... summary snipped ...]

At the risk of again diverting the thread from its original, blessed into
Shlomi's class purposes, I'd like to add my comments.

50-line perl code snippets are typically written to perform quick and
dirty tasks.  In order to make the most out of them:
1. Make it easy to reuse them.
2. If they read from one stream and write to another stream, use
   stdin/stdout rather than explicit files.  This way, the snippet can be
   used as part of a shell pipe in the future.
3. While it is not a good idea to bother to generalize a script the first
   time you write it, if you find you need to modify and reuse it, then
   modify the script in such a way that the differences between its uses
   are parameterized (for example, a search string which changes between
   uses of the script - can be parameterized).
4. When doing (3), document the script's new parameters!
5. Add comments with keywords, which will help you in the future locate
   again a script to do a particular task, by grepping over the directory
   in which you save all your quick&dirty scripts (you have such a
   directory, right?).
                                             --- Omer
WARNING TO SPAMMERS:  at http://www.zak.co.il/spamwarning.html

---

From: Tzafrir Cohen <[email-masked]>
Date: Mon, 13 Aug 2001 14:22:05 +0300 (IDT)

>  used as part of a shell pipe in the future.

Actually, <> instead of <STDIN> , becuase you may read data from a file
(and because it is shorter to write ;-))

>  time you write it, if you find you needto modify and reuse it, then

I generally try to make global "constant" variables out of things I
initially feel that "should" be parametrized. Later on, when I need to
make this availble as a parameter, it is usually easier to assign a value
to that constant, when parsing the command-line parameters. 

> 4. When doing (3), document the script's new parameters!

I usually use Getopt , and I always add a "help" option which writes a
summary of the other options. It has saved me some time even with the
simpler scripts (and I simply cut-n-paste it from other scripts).

That summary message is usually a resonable "documentation" of the
options.

-- 
Tzafrir Cohen
mailto:[email-masked]
http://www.technion.ac.il/~tzafrir

---

From: Shlomi Fish <[email-masked]>
Date: Mon, 13 Aug 2001 16:54:43 +0300 (EEST)

>    used as part of a shell pipe in the future.

Actually, it usually is a good idea to use filehandles such as IN, OUT,
FILE, etc. It is always possible to duplicate STDIN into one such
filehandle. (I think the syntax is open IN, "<&STDIN";). In any case, the
FileHandle module is also a good idea, as is the Socket module.

>    in which you save all your quick&dirty scripts (you have such a

I'm not sure I'd like to focus on scripts in my documnt. I'd like to give
advice for writing legible, maintainable perl code, whether in a module or
in a script.

Oh, and I have a hierarchy of perl scripts, programs and modules.

Regards,

	Shlomi Fish

> To unsubscribe from this group, send an email to:
> [email-masked]
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>

---

From: Omer Zak <[email-masked]>
Date: Mon, 13 Aug 2001 18:07:16 +0300 (EET DST)

On Mon, 13 Aug 2001, Shlomi Fish wrote:

> Actually, it usually is a good ideato use filehandles such as IN, OUT,
[... rest of discussion was snipped, especially as I saw no explanation
     how using filehandles *really* makes perl scripts easier to
     use                                                           ...]

OK, it seems that Shlomi's thread is destined for diversions regardless of
any goodhearted attempts to do otherwise...

The current diversion starts with the questions:
1. How do you actually use 50-line perl scripts (or programs) for?
2. What writing style of 50-line perl scripts would make it easier for you
   to use such scripts for whatever you actually use them for?

> advice for writing legible, maintainable perl code, whether in a module or

Here is the reason for the current diversion:  Shlomi wants
legible&maintainable perl code.  I want just to get my job done today and
in the future.  I believe that for this purpose, remembering to read from
stdin (or from <> - which I personally don't like, because it complicates
for me command line arguments handling and validation - no religious
argument here please - it is matter of taste for me) - is more important
than using alternative filehandle names (see above).

Does Anyone disagree with me?
If yes, what are his/her reasons?

                                             --- Omer
There is no IGLU Cabal.  Freedom of expression was suppressed there at a
whim, and people stopped discussing the important issues.
WARNING TO SPAMMERS:  at http://www.zak.co.il/spamwarning.html