Why to use warnings; and not the -w switch

use warnings; may appear to be the exact same thing as using the -w switch, but it's not quite the same. use warnings; allows fine grained control over warnings that you simply can't get with -w

For example, look at the following code:

#! /usr/bin/perl -w use strict; main->foobar($ARGV[0]); sub foobar { print "foo$_[1]bar\n"; }

If you run the program above without any arguments you will get the following output:

Use of uninitialized value in concatenation (.) or string at - line 7. foobar

Now you want warnings, but if you don't want to clutter up STDERR with the uninitialized values warning, you would have to change the script to the following:

#! /usr/bin/perl -w use strict; main->foobar($ARGV[0]); sub foobar { if ($_[1]) { print "foo$_[1]bar\n"; } else { print "foobar\n"; } }

That seems pretty inelegant, right? Plus, if you're not trying to obfusucate your code, it can unnecessarily obscure your intentions. And, to top it all off, this is a simple example. Many times in a function you'll want to use a variable whether or not it's been initialized (set to a value), and it can be irritating to get a string of these warnings. But you don't want to turn off warnings because, after all, it's more useful then it is annoying. So what to do?

The answer is use warnings;. Check out the following sample:

#! /usr/bin/perl use strict; use warnings; main->foobar($ARGV[0]); sub foobar { no warnings qw (uninitialized); print "foo$_[1]bar\n"; }

We have turned off the warning we were getting, but we are still getting other warnings (which we weren't expecting), with sub foobar. Note that no is scoped, that is once you leave the sub (or anonymous block of code) you go back to full warnings, so you don't turn off uninitialized warnings for your entire program. Plus it's easier to read.