start page | rating of books | rating of authors | reviews | copyrights

Book Home Programming PerlSearch this book

31.8. use diagnostics

use diagnostics;            # compile-time enable
use diagnostics -verbose;

enable  diagnostics;        # run-time enable
disable diagnostics;        # run-time disable

This pragma expands the normal, terse diagnostics and suppresses duplicate warnings. It augments the short versions with the more explicative and endearing descriptions found in Chapter 33, "Diagnostic Messages". Like other pragmas, it also affects the compilation phase of your program, not just the run phase.

When you use diagnostics at the start of your program, this automatically enables Perl's -w command-line switch by setting $^W to 1. The remainder of your whole compilation will then be subject to enhanced diagnostics. These still go out on STDERR.

Because of the interaction between run-time and compile-time issues, and because it's probably not a good idea anyway, you may not use no diagnostics to turn them off at compile time. However, you may control their behavior at run time using the disable and enable methods. (Make sure you do the use first, or else you won't be able to get at the methods.)

The -verbose flag first prints out the perldiag manpage's introduction before any other diagnostics are issued. The $diagnostics::PRETTY variable can be set (before the use) to generate nicer escape sequences for pagers like less(1) or more(1):

BEGIN { $diagnostics::PRETTY = 1 } 
use diagnostics;
Warnings dispatched from Perl and detected by this pragma are each displayed only once. This is useful when you're caught in a loop that's generating the same warning (like uninitialized value) over and over again. Manually generated warnings, such as those stemming from calls to warn or carp, are unaffected by this duplicate detection mechanism.

Here are some examples of using the diagnostics pragma. The following file is certain to trigger a few errors at both run time and compile time:

use diagnostics;
print NOWHERE "nothing\n";
print STDERR "\n\tThis message should be unadorned.\n";
warn "\tThis is a user warning";
print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: ";
my $a, $b = scalar <STDIN>;
print "\n";
print $x/$y;
Here's the output:
Parentheses missing around "my" list at diagtest line 6 (#1)
        
    (W parenthesis) You said something like
        
        my $foo, $bar = @_;
        
    when you meant
        
        my ($foo, $bar) = @_;

Remember that "my", "our", and "local" bind tighter than comma.

Name "main::NOWHERE" used only once: possible typo at diagtest line 2 (#2)

(W once) Typographical errors often show up as unique variable
    names.  If you had a good reason for having a unique name,
    then just mention it again somehow to suppress the message.
    The our declaration is provided for this purpose.
        
Name "main::b" used only once: possible typo at diagtest line 6 (#2)
Name "main::x" used only once: possible typo at diagtest line 8 (#2)
Name "main::y" used only once: possible typo at diagtest line 8 (#2)

Filehandle main::NOWHERE never opened at diagtest line 2 (#3)

(W unopened) An I/O operation was attempted on a filehandle that
    was never initialized.  You need to do an open() or a socket()
    call, or call a constructor from the FileHandle package.
        
        This message should be unadorned.
        This is a user warning at diagtest line 4.

DIAGNOSTIC TESTER: Please enter a <CR> here: 
Use of uninitialized value in division (/) at diagtest line 8 (#4)

(W uninitialized) An undefined value was used as if it were
    already defined.  It was interpreted as a "" or a 0, but maybe
    it was a mistake.  To suppress this warning assign a defined
    value to your variables.
        
Illegal division by zero at diagtest line 8 (#5)

(F) You tried to divide a number by 0.  Either something was
    wrong in your logic, or you need to put a conditional in to
    guard against meaningless input.
        
Uncaught exception from user code:
        Illegal division by zero at diagtest line 8.

Diagnostic messages derive from the perldiag.pod file. If an extant $SIG{__WARN__} handler is discovered, this will still be honored, but only after the diagnostics::splainthis function (the pragma's $SIG{__WARN__} interceptor) has had its way with your warnings. Perl does not currently support stacked handlers, so this is the best we can do for now. There is a $diagnostics::DEBUG variable you may set if you're desperately curious about what sorts of things are being intercepted:

BEGIN { $diagnostics::DEBUG = 1 } 
use diagnostics;



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.