Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warnings::warn and FATAL categories in Perl

Tags:

warnings

perl

I must be understanding the warnings documentation wrong. The way I read it, this code:

use warnings;
use warnings FATAL => 'all';
warnings::warn('numeric', 'blarg');
print "finished\n";

Should print the 'blarg' warning and die since I've asked for all warnings to be fatal. However, when I run the code I get:

$> /opt/local/bin/perl x.pl 
blarg at x.pl line 3
finished

Can somone help me understand why I can't get warn to die?

like image 876
Josh McAdams Avatar asked Oct 20 '09 04:10

Josh McAdams


People also ask

What are warnings in Perl?

use warnings; When the warning pragma is used, the compiler will check for errors, will issue warnings against the code, and will disallow certain programming constructs and techniques. This pragma sends a warning whenever a possible typographical error and looks for possible problems.

Why use strict and warnings Perl?

It helps you find typing mistakes, it warns you whenever it sees something wrong with your program. It would help you find mistakes in your program faster. Note: The most important point to note here is that “use strict” would abort the execution of program if it finds errors.

What is pragma in Perl?

In perl (as in all programming languages), a "pragma" is a directive that specifies how the compiler (or in perl's case, the interpreter) should process its input. They are not part of the language per se, but are a sort of command-line option that tells the interpreter how to behave.

What is Perl strict?

The strict pragma disables certain Perl expressions that could behave unexpectedly or are difficult to debug, turning them into errors. The effect of this pragma is limited to the current file or scope block. If no import list is supplied, all possible restrictions are assumed.


1 Answers

Okay. This is ugly. I had a post half-prepared explaining this as a bug in warnings, and then I realized it's not, it's just a really evil subtlety in the way warnings works.

Warnings starts looking for a relevant stack frame to get the warning bits from in warnings::warn's caller's caller. The idea is that you're writing some module and you use warnings::warn or warnings::warnif in your functions, and whether or not the warning is printed (or fatal) depends on the use warnings setting in scope in the code that uses your module. There's no option provided to have it start at caller(1) instead of caller(2), so the effect you want isn't possible.

An example of code that does work (and demonstrates how this interface was expected to be used by whoever wrote it):

package Foo;
require warnings;

sub bail {
  warnings::warnif('numeric', "You fool! You divided by zero!");
}

package main;
use warnings FATAL => all;

Foo::bail();
print "Will never be reached\n";

And you can't defeat the way it works by just adding another level of subroutines, because it takes the flags from the first caller that's in a different package from the caller of warn/warnif/enable/etc.

like image 186
hobbs Avatar answered Nov 08 '22 22:11

hobbs