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):
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.BEGIN { $diagnostics::PRETTY = 1 } use diagnostics;
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:
Here's the output: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;
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;
Copyright © 2001 O'Reilly & Associates. All rights reserved.