Previous Page
Next Page

18.8. Warnings

Always turn on warnings explicitly.

If you're developing under Perl 5.6 or later, always use warnings at the start of each file. Under earlier versions of Perl, always use the -w command-line flag, or set the $WARNING variable (available from use English) to a true value.

Perl's warning system is invaluable. It can detect more than 200 different questionable programming practices, including common errors like using the wrong sigil on an array access; trying to read an output stream (or vice versa); leaving parentheses off ambiguous declarations; runaway strings with no closing delimiter; dyslexic assignment operators (=-, =+, etc.); using non-numbers as numbers; using | instead of ||, or || instead of or; misspelling a package or class name; mixing up \1 and $1 in a regex; ambiguous subroutine/function calls; and improbable control flow (e.g., returning from a subroutine via a call to next).

Some of these warnings are enabled by default, but all of them are worth enabling.

Not taking advantage of these warnings can result in code like this, which compiles without complaint, even though it has (at least) nineteen distinct problems:

    my $n = 9;
    my $list = (1..$n);

    my $n = <TTY>;

    print ("\n" x lOO, keys %$list), "\n";
    print $list[$i];

    sub keys ($list) {
        $list ||= $_[1], \@default_list;
        push digits, @{$list} =~ m/([A-Za-\d])/g;
        return uc \1;
    }

Under use warnings the awful truth can be revealed:


    "my" variable $n masks earlier declaration in same scope at caveat.pl line 4.
    print (...) interpreted as function at caveat.pl line 6.
    Illegal character in prototype for main::keys : $list at caveat.pl line 9.
    Unquoted string "digits" may clash with future reserved word at caveat.pl line 11.
    False [] range "a-\d" in regex; marked by <-- HERE in m/([A-Za-\d <-- HERE ])/
    at caveat.pl line 11.

    Applying pattern match (m//) to @array will act on scalar(@array) at
    caveat.pl line 11.
    Array @digits missing the @ in argument 1 of push(  ) at caveat.pl line 11.
    Useless use of reference constructor in void context at caveat.pl line 10.
    Useless use of a constant in void context at caveat.pl line 6.
    Name "main::list" used only once: possible typo at caveat.pl line 7.
    Name "main::default_list" used only once: possible typo at caveat.pl line 10.
    Name "main::TTY" used only once: possible typo at caveat.pl line 4.
    Name "main::digits" used only once: possible typo at caveat.pl line 11.
    Name "main::i" used only once: possible typo at caveat.pl line 7.
    Use of uninitialized value in range (or flip) at caveat.pl line 2.
    readline(  ) on unopened filehandle TTY at caveat.pl line 4.
    Argument "lOO" isn't numeric in repeat (x) at caveat.pl line 6.
    Use of uninitialized value in array element at caveat.pl line 7.
    Use of uninitialized value in print at caveat.pl line 7.

Note that it may still be appropriate to comment out the use warnings line when your application or module is deployed, especially if non-technical users will interact with it, or if it will run in a CGI or other embedded environment. Issuing warnings in these contexts can needlessly alarm users, or cause server errors.

Don't remove the use warnings completely, though; when something goes wrong, you'll want to uncomment it again so the reinstated warnings can help you locate and fix the problem.

    Previous Page
    Next Page