itub has asked for the wisdom of the Perl Monks concerning the following question:

The perllexwarn document describes how to enable and disable specific categories of warnings, and it shows the category tree that is used for classifying the warnings. However, sometimes it takes a little bit of trial and error to figure out the category for a specific warning. For example, today I saw this warning for the first time:
Value of <HANDLE> construct can be "0"; test with defined() at -e line 1

This comes from a line like this:

$s = <$fh> or die;

Let's say that I want to disable this type of warning. Which type is it? Since none of the categories seemed particularly relevant, I decided to try no warnings qw(misc), and it worked! Ok, so the categories are reasonably intuitive. But has anyone compiled a list of warnings by category? That would be helpful for the more ambiguous cases, or for educational purposes.

Replies are listed 'Best First'.
Re: A list of warnings by category?
by Fletch (Bishop) on Nov 20, 2004 at 03:26 UTC

    See perldoc perldiag (and also related perldoc diagnostics and perldoc splain). Warnings are noted with a (W category) in their entry.

      Thanks, that's exactly what I was looking for! I don't know how I missed the line in perllexwarn that said: "To determine which category a specific warning has been assigned to see perldiag." Shame on me...
Re: A list of warnings by category?
by theorbtwo (Prior) on Nov 20, 2004 at 08:56 UTC

    The quick answer is perldiag. If you still want just what you asked for -- a list of warnings by category, try the following one-liner:

    perl -MData::Dumper -ne '$item=$1 if /^=item (.*)/; push @{$warnings{$1}}, $item if /\(W ([^)]*)\)/; END {print Dumper \%warnings}' /usr/share/perl/5.8/pod/perldiag.pod

    (Make sure to adjust the location of perldiag as approprate to your system -- perldoc -l perldiag will show you where it is.)


    You want to know how it works? Well, let's start by showing you the code that I left out (IE that the -n option implies). The simpilest way to do this, and to do some reformatting at the same time, is to use -MO=Deparse, as in perl -MO=Deparse,-p -MData::Dumper -ne '$item=$1 if /^=item (.*)/; push @{$warnings{$1}}, $item if /\(W ([^)]*)\)/; END {print Dumper \%warnings}' That gives:

    use Data::Dumper; LINE: while (defined($_ = <ARGV>)) { $item = $1 if /^=item (.*)/; push @{$warnings{$1};}, $item if /\(W ([^)]*)\)/; sub END { print Dumper(\%warnings); } ; }
    , which isn't quite readable. I'll change some things around to make it a bit more idiomatic.
    use Data::Dumper; while (defined($_ = <ARGV>)) { if (/^=item (.*)/) { $item = $1; } if (/\(W ([^)]*)\)/) { push @{$warnings{$1}}, $item; } } print Dumper(\%warnings);

    I got rid of some superflous semicolons, the unused label LINE, and changed FOO if BAR to if (BAR) {FOO}. Most importantly, I moved the sub END { } bit to where it actually gets run -- as the program is ending.

    But it still doesn't do some things you shouldn't do in any program longer then one line, even though it's no longer a one-liner -- it needs warnings and strict.

    use Data::Dumper; use warnings; use strict; my ($item, %warnings); while (defined($_ = <ARGV>)) { if (/^=item (.*)/) { $item = $1; } if (/\(W ([^)]*)\)/) { push @{$warnings{$1}}, $item; } } print Dumper(\%warnings);

    So, now that we've changed it from a confusing little oneliner to a real program, can you figure out how it works? It runs through each line of the file provided on the command line, or standard input if none was given. If the line starts with =item and a space, we save the rest of the line in the variable $item for later. If it contains a begin-paren, followed by a W, a space, a bunch of non-parenthesis characters, and then an end paren, then we add the contents of $item to the end of the array-reference @{ ... } given in the slot of %warnings given by $1 (the bunch of non-parenthesis characters from the line we're on). Then, once we're finished with all the lines in the ARGV filehandle, we dump out %warnings.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: A list of warnings by category?
by Limbic~Region (Chancellor) on Nov 19, 2004 at 23:14 UTC
    itub,
    I haven't ran into too many warnings that I couldn't figure out from the message, but in the cases I did - turning on use diagnostics was all that was needed to find the right thing to fix/turn off.

    Cheers - L~R

Re: A list of warnings by category?
by diotalevi (Canon) on Nov 19, 2004 at 22:56 UTC
    Any list you create will have to account for differences in versions. This stuff changes over time.
      Any list you create will have to account for differences in versions. This stuff changes over time.
      I think that's inexact. If you mean specific warnings move from one category to another, then a program may start spitting out previously inhibited warnings when perl is updated. This is not good behavior, and should only be done when something *big* has changed in the language (like we got it extremely wrong the first time).

      If you mean new warnings are added, then yes, that's allowable. But it's not much problem for programmers, because they aren't interested in non-existent warnings.

      Concerning the former, I've recently seen an library (in another language) where the error numbers are matched to error messages. However, the mapping isn't stable, but the messages (mostly) are, so error handlers parse the error messages to decide which error occurred! TIMTOWTFIU!

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

      Any list you create will have to account for differences in versions. This stuff changes over time.
      Do you mean something that perhaps goes out with the release...something like perldoc perhaps? I see no problem adding something like 'perlwarncat' to the perldoc library. And, if it's part of the distribution, no matter which version you get, it'll be correct. Just like perlreftut or anything else.

      thor

      Feel the white light, the light within
      Be your own disciple, fan the sparks of will
      For all of us waiting, your kingdom will come

Re: A list of warnings by category?
by PodMaster (Abbot) on Nov 19, 2004 at 23:18 UTC
    If you open up warnings.pm, you'll see that there are 3 global hashes which contain this information, %DeadBits, %Bits, and %Offsets. If you examine import/unimport you'll see how they're used.

    update: Ignore me for now, got confused after hitting preview.

    This list should be compiled from perl sources when you compile perl, and here's how it might be done (UNtested,just slapped it together):

    final update: I hadn't noticed that perldiag had entries like (W bareword), but I haven't read perldiag in forever, oh well :)

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.