Приглашаем посетить
Чарская (charskaya.lit-info.ru)

Section 18.7.  Strictures

Previous
Table of Contents
Next

18.7. Strictures

Always use strict.

Making use strict your default will help perl (the interpreter) pick up a range of frequently made mistakes caused by Perl (the language) being overhelpful. For example, use strict detects and reportsat compile timethe common error of writing:

    my $list = get_list(  );

    # and later...

    print $list[-1];             # Oops! Wrong variable

instead of:


    my $list_ref = get_list(  );

    
# and later...
print $list_ref->[-1];

But it's also important not to rely too heavily on use strict, or to assume that it's infallible. For example, it won't pick up that incorrect array access in the following example:

    my @list;

    # and later in the same scope...

    my $list = get_list(  );

    # and later...

    print $list[-1];

That's because now the problem with $list[-1] isn't just that someone forgot the arrow; it's that they're referring to the wrong (valid) variable.

Similarly, the following code contains both symbolic references and unqualified package variables, both of which use strict is supposed to prevent. Yet it compiles without even a warning:

    use strict;
    use warnings;
    use Data::Dumper;

    use Readonly;
    Readonly my $DUMP => 'Data::Dumper::Dumper';
    Readonly my $MAX  => 10;

    # and later...

    sub dump_a {
        my $dump = \&{$DUMP};                  # Symbolic reference

        my @a = (0..$MAX);

        for my $i (0..$#a) {
            $a->[$MAX-$i] = $a->[$i];          # Oops! Wrong variables
            print $dump->($a[$i]);
        }

        return;
    }

The uncaught symbolic reference is in \&{$DUMP}, where $DUMP contains a string, not a subroutine reference. The symbolic access is ignored because dump_at( ) is never called, so use strict never gets the change to detect the symbolic reference.

The uncaught package variable is the scalar $a in $a->[$i] and $a->[$MAX-$i]. That's almost certainly supposed to be $a[$i], as it is in the print statement. Perhaps the:

    my @a = (0..$MAX);

line was originally:

    my $a = [0..$MAX];

and, when it was changed, the rest of the subroutine was incompletely updated. After all, use strict will point out any uses of $a that might have been missed, won't it?

In this particular case, it doesn't. The package variables $a and $b are exempt from use strict qw( vars ), because they're frequently required in sort blocks, and no-one wants to have to write:

    @ordered_results = sort { our ($a, $b); $b <=> $a } @results;

And they're not the only variables that are invulnerable to use strict. Other "stealth" package variables include $ARGV, @ARGV, @INC, %INC, %ENV, %SIG, and occasionally @F (in the main package under the -a flag). Moreover, because use strict exempts the entire symbol table entry for each of the previous variables, none of the following are caught either: %ARGV, $INC, @ENV, $ENV, @SIG, and $SIG.

This doesn't mean that using strict isn't a good practice; it most definitely is. But it's critical to think of it as a tool, not as a crutch.

    Previous
    Table of Contents
    Next