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;