http://www.perlmonks.org?node_id=695165

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

Does the -w in the shebang line and the 'use warnings;' mean the same thing? And what are things like the '-w' called (eg the -f or -d to specify file or directory)? Google doesn't like searching for one-letter things which makes it nearly impossible for me to find out!

Replies are listed 'Best First'.
Re: shebang arguments
by friedo (Prior) on Jul 02, 2008 at 18:14 UTC

    They're similar, but not exactly the same. Putting -w in the command line (or the shebang) will turn on warnings globally, for all the Perl code loaded by that process.

    On the other hand, use warnings is a "lexical pragma," and only applies in the block in which it's used. If you put it at the top of a script or module, then it will apply for that entire file (this is called file scope.) Inside a block, it applies only for that block:

    #!/usr/bin/perl print "no warnings out here!" . $undef_var; { use warnings; # now warnings are turned on print "this will warn" . $undef_var; } # now warnings are off again.

    (Note: Try running that with and without -w to see the difference.

    Typically, it's a good idea to use warnings in your file scope, which allows you to occasionally turn them off in small blocks (using no warnings) if you absolutely must do something that will generate a warning. See perllexwarn for the gory details.

    And what are things like the '-w' called (eg the -f or -d to specify file or directory)?

    Those are called command-line switches or arguments, and perl's are all documented in perlrun.

      Thanks very much everyone, especially friedo for the comprehensive answer :-)

      I found the answer to '-f or -d' here:
      http://perldoc.perl.org/functions/-X.html

Re: shebang arguments
by pc88mxer (Vicar) on Jul 02, 2008 at 18:16 UTC
    It's easier to search the perldoc documentation. The runtime switches are documented in perldoc perlrun.

    Also, here's what perldoc warnings says:

        The "warnings" pragma is a replacement for the command line flag "-w",
        but the pragma is limited to the enclosing block, while the flag is
        global.  See perllexwarn for more information.
    
Re: shebang arguments
by ikegami (Patriarch) on Jul 02, 2008 at 19:33 UTC
    Not quite. -w is equivalent to $^W = 1;, which turns on warnings globally. use warnings; is lexically scoped, which means it only affects the block (or file) it's in.
Re: shebang arguments
by apl (Monsignor) on Jul 02, 2008 at 18:17 UTC
    perlrun is a good summary of the Perl runtime switches.

      Also, in 5.8.8 and 5.10 there is a difference between -w and -W (note lower / upper case). The link to perlrun, above is older and doesn't mention the distinction. -W (uppercase) allows no override with no warnings; and so might be used in development with -w in prod if you want the chore of fine tuning your prod warnings with no warnings; as opposed to taking them out altogether like DrHyde.


      #my sig used to say 'I humbly seek wisdom. '. Now it says:
      use strict;
      use warnings;
      I humbly seek wisdom.
Re: shebang arguments
by Argel (Prior) on Jul 02, 2008 at 22:50 UTC
    Another difference is that if someone runs the perl command against your script then the shebang line will be ignored while "use warnings" will still be enforced. This is particularly relevant on Windows which does not use the shebang line.

    My personal view is that the -w method is "old school" and these days you should be using the warnings pragma instead.

      Another difference is that if someone runs the perl command against your script then the shebang line will be ignored while "use warnings" will still be enforced.

      It may be ignored by the shell, but it isn't ignored by perl.

      foo.pl: #!/usr/bin/perl -w $x = $y . $z; $ ./foo.pl Name "main::y" used only once: possible typo at ./foo.pl line 3. Name "main::z" used only once: possible typo at ./foo.pl line 3. Name "main::x" used only once: possible typo at ./foo.pl line 3. Use of uninitialized value in concatenation (.) or string at ./foo.pl +line 3. Use of uninitialized value in concatenation (.) or string at ./foo.pl +line 3. $ perl foo.pl Name "main::y" used only once: possible typo at foo.pl line 3. Name "main::z" used only once: possible typo at foo.pl line 3. Name "main::x" used only once: possible typo at foo.pl line 3. Use of uninitialized value in concatenation (.) or string at foo.pl li +ne 3. Use of uninitialized value in concatenation (.) or string at foo.pl li +ne 3.

      BTW, you can use perl -X to force it to ignore -w on the shebang, if you want.

        Ahh, so perl actually checks! Nice!

      Just because something is old and there's a new way of doing it doesn't mean that you should abandon the old. For one thing, 'use warnings' won't work on some older perls. If you care about them - and I do - then 'use warnings' is a bad idea.

      I do 'use warnings' when developing my code, but I try to remember to remove it when I do a release. I usually forget and am prompted to do so by test failures being reported by the CPAN testers. Quite often those failure reports come from my own testing boxes :-)

        I agree that just because something is new does not automatically mean you should abandon the old method in favor of it. But on the other hand if a paradigm shift occurs then it likely means the new way is the better way. And in this case the impression I get is that the Perl community has shifted away from -w in favor of the warnings pragma. Hence why I called -w "old school".

        I think it goes without saying that you would use "old school" methods with older versions of Perl. That's part of what "old school" implies.

        P.S. Sounds like you should firewall off your test servers! ;-)

Re: shebang arguments
by Anonymous Monk on Jul 02, 2008 at 19:08 UTC
    I think I also smell a confusion between the runtime switches of the perl interpereter that are documented in 'perlrun' and the filetest functions in the perl language documented in 'perlfunc'.