Документация
HTML CSS PHP PERL другое

Section 6.3.  Other Postfix Modifiers

 
Previous
Table of Contents
Next

6.3. Other Postfix Modifiers

Don't use postfix unless, for, while, or until.

The special dispensation to use postfix if in flow-control statements doesn't extend to any other types of statements. Nor does it extend to any of the other postfix statement modifiers.

The postfix looping modifiers create particular maintenance problems because they place the control flow (i.e., the loop specifier) to the right of the statement it controls. For example, a loop like:

    print for grep {defined $_} @generated_lines;

makes it harder to notice the looped flow of control, especially if you also have statements like:

    print $fh grep {defined $_} @generated_lines;

A proper for loop makes the iteration much more obvious:


    for my $line (grep {defined $_} @generated_lines) {
        print $line;
    }

Note too that it's not possible to give a readable name to the iterator variable of a postfix loop, nor to easily nest conditional tests inside such a loop. Instead of being able to write the code in a straightforward, explicit, easy-to-follow, and extensible way:


    for my $line (@generated_lines) {
        if (defined $line) {
            print lc $line;
        }
    }

you're forced to rely on boolean operations, and tempted by default behaviours:

    defined and print lc for @generated_lines;

Worse still, using a postfix loop will sometime make it necessary to use explicit $_, which makes the resulting code much harder to understand:

    $_ = lc for @generated_lines;

The same code is much clearer in block form:


    for my $line (@generated_lines) {
        $line = lc $line;
    }

This disparity in readability grows greater as the number of statements to be iterated increases:

    defined
    and print lc
    and (s{\A cmd}{}xms or 1)
    and push @non_cmds, $_
        for @generated_lines;

at which point most people would surely switch over to:


    for my $line (@generated_lines) {
        if (defined $line) {
            print lc $line;
            $line =~ s{\A cmd}{}xms;
            push @non_cmds, $line;
        }
    }

So why not start out that way? Starting with the postfix form means that you will almost inevitably have to rewrite some existing code using the block form. And rewriting existing code is a great way to introduce new bugs.

    Previous
    Table of Contents
    Next
    © 2000- NIV