Should we avoid turning on warnings for the complete program? [closed]
I have subscribed to beginners@perl.org
A discussion was going on there and a guy was suggesting that you should not use
#!/usr/bin/perl -w
This will turn on the warning for the complete program. He said:
Please do not use -w in the hashbang, it forces warnings everywhere, even when modules didn't want warnings. You'll get weird error messages if you leave that in. Instead just write "use warnings;" at the top of your code and you'll be fine. :)
It activates warnings for code you did not write.
It is an extremely good idea to enable warnings for all code you write yourself. However if you enable it for code written by authors who did not want warnings, or for old modules, then you will get pointless messages you cannot fix.
I said: So you want to say we should put use warnings only in some part of the code.
He replied: Yes, specifically: Only the code you wrote yourself.
instead of doing this you should use the warnings
pragma in the code you wrote yourself not for the complete program.
I used to write -w in the shebang so that I can turn on the warnings for the complete program. But after this discussion I am confused whether should I follow that guy or not. Is he right? Should we avoid turning on warnings for the complete program?
Usually what I follow is
#!/usr/bin/perl
use strict;
use warnings;
#now start actual coding from here
#...............................
#...............................
You've fairly accurately described the situation. -w turns on warnings globally (across all modules, unless they specifically turn them off lexically). use warnings
behaves lexically, not affecting what happens in other modules.
That being said, I don't see this as a matter of which one is better. It's really a matter of which behavior you want. We wouldn't say that foreach
is better than while
without knowing the context of the assertion. If you desire the behavior of turning on warnings globally, by all means, do so. If you want to turn on warnings in a way that doesn't impact external modules, do that.
Warnings, in my opinion, are a development and debugging tool. I try to program always with warnings 'on' (in my own code). Whether or not I deploy the code to production with warnings enabled is a different story. There are a lot of factors that contribute to the decision as to whether warnings should be enabled in production code. Naturally the goal is to program warning-free. So if warnings are enabled in production code, and one slips through, that shouldn't be happening if we did our job right. But if one does slip through, would that information be helpful to anyone or not? And would the helpfulness outweigh the added noise and potential risks of exposing information about the program to unknown end users?
As for the topic of writing warnings-free code: Yes, that should always be the goal. There are a LOT of warnings though. my @list = qw/ Just another Perl hacker, /;
will trigger a warning. This warning is aimed at helping me to realize that I may have made a mistake (embedding a comma in a qw// list). But as many here know, that phrase does end with a comma. The bigger question here is whether I really intended to make a list of the words as opposed to a single string. So lets say that I do need a list of words, and one word legitimately needs a comma at the end of it. In that case, the warning is frivolous. I have two options. One, say my ( @list ) = ( 'Just', 'another', 'Perl', 'hacker,' );
, or two, say my ( @list ) = do{ no warnings 'qw'; qw/Just another Perl hacker,/; };
. They're both a lot of typing, and in this contrived example it's probably better to just bite the bullet and use the first option. But that doesn't mean the second option is buggy, and there may be many less-contrived examples of where the warning isn't desirable.
Now lets look at a situation where it may be useful to trigger a warning in another module: You've been tearing your hair out as to why you're not getting expected results back from XYZ module. You could pepper your code with print statements, you could dump your datastructure, you could dive into the Perl debugger... but what's wrong with enabling warnings globally, if just for a single run to see if something you are doing is creating an issue at a distance, a silent failure within a module? Obviously a robustly written module would carp to you if you feed it trash. But should/would.... that's up to the module's author. What's up to you is that you can elevate to a warning something that may have been silent failure before. Given that it's such a simple debugging step, it may be worth a try before stepping through the code with the debugger.
You have already found this, but for the sake of other readers, perllexwarn discusses the difference between -w, use warnings, and $^W.
Quoth the documentation:
BUGS
The -w switch is not mandatory.
Use -w
. Any module that gives "odd warnings" when -w is enabled is poorly coded and should probably be avoided, and old modules should be upgraded.
Turn on warnings, either with -w
or an explicit use warnings;
until it causes you trouble with someone else's module. It's not that the guy is actively wrong so much as he is facing unusual circumstances that most people will not run into.
At the point where a module does give warnings that you can't fix, consider selectively disabling warnings while you load that module - but consider whether there is a better alternative module without the warnings. I've not run across problems with many modules in the last few years; I've never needed to use warnings selectively. And I have a lot of modules installed (though I use fewer of them than I probably should).
I'm the one who originally made the comments he mentions and i was specifically thinking about this class of modules:
- http://metacpan.org/author/MLEHMANN
- http://deps.cpantesters.org/depended-on-by.pl?dist=common-sense-3.4
Most of them are great tools that do strange things and have good reasons to avoid warnings. Especially the event loops, where performance is key.
Now, keep in mind i said this on the beginner mailing list. My advice was targeted at people who can barely debug their own code. Having them enable warnings globally, in code they didn't write, don't control and very often don't even understand is just asking for trouble. Often they won't even understand (or remember) why they are getting these warnings.
-w
should only be used when you understand exactly what it gets you.
精彩评论