Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Get stricter with use warnings FATAL => 'all';

by toolic (Bishop)
on Oct 12, 2011 at 14:29 UTC ( [id://931025]=perlmeditation: print w/replies, xml ) Need Help??

If you
use warnings;
I suggest you switch to
use warnings FATAL => 'all';
to promote all warnings to errors and die immediately on the first warning (see Fatal Warnings).

Why you should use this

It is more effective at finding bugs in your code than plain old use warnings;.

It is a widely-regarded good Perl coding practice to add use warnings; to your code because you want perl to notify you of impending problems. In my experience, the warnings have always pointed to a bug in my code.

The issue is that, in some common usage scenarios, it is too easy to miss the warning messages unless you are looking for them. They can be hard to spot even if your code generates a small amount of output, not to mention anything that scrolls off the screen. Or, if your output (STDOUT and STDERR) is redirected to a log file which you typically do not look at, then you wouldn't see the warning messages. FATAL => 'all' will kill your program dead so that there is no way to miss the warnings. This is no different from use strict;, which dies immediately.

Although you may miss the warnings (without FATAL), there's a 100% chance your customers will see them. It's a little unprofessional looking if your code is spewing gobs of warning messages.

FATAL can also help prevent you from wasting your time if there are multiple warnings. Often times, the last warning is the most visible, but it's the first warning that you should target.

How do I start using this?

Just add the line to your script template/boilerplate (or replace your existing use warnings; line). Any new code you create will have it. I've had this in place for a couple years now, and it took no time to adapt to the new level of strictness.

But some warnings really aren't important to me.

You can always selectively disable warnings. It works just like warnings. Simply localize as you would normally:
{ no warnings 'uninitialized'; # etc. }

Isn't this too strict?

No. The reason you started using warnings in the first place was because the Monks told you to so that perl could notify you that it's probably not going to Do What You Want. If you are debugging, you can temporarily ease off by commenting out FATAL. Sometimes it is useful to see multiple warnings at once, just to assess how bad the damage really is:
use warnings ; # FATAL => 'all';

toolic, you have no idea what you're talking about because...

Please enlighten me if I have overlooked something. I see no downside; do you?

Related discussions

Updated: added direct link to fatal docs.

Replies are listed 'Best First'.
Re: Get stricter with use warnings FATAL => 'all';
by mje (Curate) on Oct 12, 2011 at 18:56 UTC

    As often is the case there are two sides to each argument. This would not work for some code I use as warnings are often issued with warn() or Log::Log4perl::logwarn as a warning (something you should take notice of but it is not necessarily a code bug). If I just indiscriminately set warnigs are promoted to fatal a lot of code would stop working. This is partly where the Perl system of warnings breaks down. Warnings issued by Perl itself are probably worth knowing (and perhaps worth promoting to fatal so you can actually add code to cope with it) but application code can also call warn and in this case it probably means - take note - something to be aware of - but not necessarily fatal.

      mje,

      Thank you for the feedback.

      This would not work for some code I use as warnings are often issued with warn()
      If you are referring to warn, then there is no problem. use warnings FATAL => 'all'; will not cause a warn to die, as shown by this example:
      use warnings FATAL => 'all'; use strict; warn "foo\n"; warn "bar\n"; __END__ foo bar

      I have never used Log::Log4perl (or any similar logging modules), but I would be surprised if it promoted its warnings to fatals. When I get a chance, I will try to figure out how to use the Log module to confirm your assertion. Feel free to post a small example which proves this. Thanks for pointing this out.

      UPDATE: Here is my 1st attempt at using Log::Log4perl. In this mode, the warning is not promoted to a fatal. I have more to learn about the module.

      use strict; use warnings FATAL => 'all'; use Log::Log4perl qw(:easy); Log::Log4perl->easy_init($DEBUG); WARN("foo"); DEBUG "A low-level message"; ERROR "Won't make it until level gets increased to ERROR"; WARN('bar'); __END__ 2011/10/12 21:05:08 foo 2011/10/12 21:05:08 A low-level message 2011/10/12 21:05:08 Won't make it until level gets increased to ERROR 2011/10/12 21:05:08 bar
      I also tried the Core Log::Message module, and I did not observe warnings turning into fatals there either.

        toolic thanks for that. My mistake. I believed (erroneously) that FATAL => 'all' caused all calls to warn to die. Having reread the documentation it appears I still don't get FATAL => 'all' - do you know where that is documented? I can only find FATAL mentioned in perldoc warnings but it is not clear how this works.

Re: Get stricter with use warnings FATAL => 'all';
by JavaFan (Canon) on Oct 13, 2011 at 00:20 UTC
    Although you may miss the warnings (without FATAL), there's a 100% chance your customers will see them.
    What kind of broad assumption are you making here? Lots of people work in environments where their customers come via a webserver. A webserver which logs the messages found on STDERR instead of sending them over the line to the customer.

    My customers prefer a page that just does the right thing, instead of dying when Perl behaves like a toddler spotting a spider because it saw a comma inside a qw.

    Warnings are warnings. Cases where Perl thinks, you're probably just right, and I will carry on, because, really, there's nothing actually holding me back, but just in case, you may want to look at this one of these days. Warnings most definitely are not errors. On errors, Perl dies. On warnings, it continues. Rightly so.

    Now, for me, if there's anything I'd change about use warnings;, it's changing the use to a no. Or perhaps:

    no warnings 'all'; use warnings 'uninitialized';
Re: Get stricter with use warnings FATAL => 'all';
by JavaFan (Canon) on Oct 13, 2011 at 00:26 UTC
    Please enlighten me if I have overlooked something. I see no downside; do you?
    Car maker: instead of allowing people to continue driving when we are now showing an orange light, let's shut down the engine, and require the car to come in to the shop before it can be restarted again. I see no downside; do you?
      Are you suggesting scripts are subject to wear and tear so they need to be serviced every 100000 code lines executed or something? :-)

      "You've got a cracked file globber seal causing memory leak. Also, when was the last time you replaced the punctuation?"

      -- Time flies when you don't know what you're doing
        Are you suggesting scripts are subject to wear and tear so they need to be serviced every 100000 code lines executed or something?
        Unfortunately, it is like that. The script itself does not wear, but the environment changes: you upgrade the OS, replace hardware, and change your mind. Maintaining a large program can be as hard as developing it.
        So, everything is static? Why even bother with warnings? Run a linter just once, instead of checking for warning on each run of your program!
Re: Get stricter with use warnings FATAL => 'all';
by Anonymous Monk on Oct 12, 2011 at 14:43 UTC
      overlooked
      I didn't overlook those links, as they are indirectly part of the "Related Discussion" section.
      "Common"
      Your quotation fingers imply facetiousness. Yes, there is a pitfall if you use eval in those ways.
Re: Get stricter with use warnings FATAL => 'all';
by afoken (Chancellor) on Oct 15, 2011 at 20:11 UTC

    Hmmm, I can see some use in making warnings fatal, especially for debugging. But JavaFan's two replys are a good point: Harmless warnings should not kill production code. They could (and perhaps should) be logged, so errors can be debugged later.

    Code will remain mostly without FATAL => 'all'. Except when you are debugging or a module author thinks that his code needs FATAL => 'all' enabled by default. But when you are debugging, you should not need to hack FATAL => 'all' into each and every file. There should be a way to force FATAL => 'all' from outside the code. Perhaps with a command line parameter or an environment variable. For extra bonus points, forcing FATAL => 'all' could be limited to a set of modules (list? regexp?).

    Carp has a similar mechanism that you can enable by including -MCarp=verbose on the perl command line or in $ENV{'PERL5OPT'}. DBI has $ENV{'DBI_TRACE'}.

    A simple-minded aproach could be ...

    push @_,FATAL => 'all' if $ENV{'PERL_FATAL_WARNINGS'};

    ... as the first line in sub warnings::import. It would affect only code that use warnings. For more, perl will probably need some patches.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Get stricter with use warnings FATAL => 'all';
by sundialsvc4 (Abbot) on Oct 13, 2011 at 12:46 UTC

    I personally find an easy-to-see middle ground here.   This is a good facility to know about, and to get some exposure here in Meditations.   I don’t personally feel that it should be seen as a “mantra,” as an always-good thing such as use warnings itself is.   It is very good to point out that this choice exists to be made if you choose to make it.   I do not personally share the opinion that it is a choice that you always should (or can) make.   I’m not ready to categorically declare that “in all cases, this is Better Goodness.™”   (And by that I do not mean to imply that I think you are making such a blanket declaration, either.)   I am glad that you made this meditation.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://931025]
Front-paged by keszler
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-03-29 00:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found