I read that it is better to use warnings; instead of placing a -w at the end of the shebang.
What is the difference between the two?
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 and the list of built-in warning categories.
– warnings documentation
The advantage of use warnings is that it can be switched off, and only affects the immediate scope.
Consider for example a module that uses operations that would emit warnings:
package Idiotic;
sub stuff {
1 + undef;
}
Then we get a warning if we do
#!perl -w
use Idiotic; # oops, -w is global
Idiotic::stuff();
but don't get any warning with
#!perl
use warnings; # pragmas are scoped, yay!
use Idiotic;
Idiotic::stuff();
Yes, there is a difference, from warnings:
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.
-w will enable warnings in included code (via use, etc.), and that may not be desirable.
Related
Is there a way I can suppress uninitialized Perl variable warning for only few libraries out of all the libraries used in a Perl file?
I can't think of any reason this would be a good idea, surely use of an uninitialised variable is a bug which ever angle you look at it from?
However, you can turn the warnings off with:
no warnings 'uninitialized';
And on again with:
use warnings 'uninitialized';
You can disable the warnings for a single statement if you surround it with these two statements.
You probably used -w, which enables warnings throughout the interpreter (though it can be overridden using local $^W = 0; or no warnings;).
It's not a bad thing to use -w. All modules should tolerate this or defend against it (using no warnings;). But some aren't "warnings-safe".
It's more conventional to place use warnings; in each of your scripts and modules. This is method of enabling warnings is less intrusive since it won't affect other third-party modules used by your script and modules.
If you're able to modify the offending module(s), you can add no warnings 'uninitialized'; to the module itself, outside of any sub declarations, and it will disable that category of warnings for all code in the module, as demonstrated with these two bits of code:
In warntest:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use lib '.';
use UndefMod;
my $x;
say "Main before: $x";
UndefMod::test_mod;
say "Main after: $x";
In UndefMod.pm (in the same directory):
package UndefMod;
use strict;
use warnings;
use 5.010;
no warnings 'uninitialized';
sub test_mod {
my $x;
say "Module: $x";
}
1;
When run, this produces "Use of uninitialized value" warnings for both says in warntest, but no warning for the say in UndefMod, thus showing that either file's warnings setting has no effect on the other.
Of course, you may not be able to modify the module source, in which case you may be out of luck. Perl's scoping rules don't generally allow you to modify the warnings/no warnings state of a scope from outside that scope. (I say "may" and "generally" because there may be some black magic to hack around that, probably at least related to the magic behind PadWalker, but such things are beyond my ken.)
I inherited some perl code that of course doesn't use either strict or warnings, and I keep using uninitialized variables and the like.
I'd like to bracket the sections of code that I'm modifying like this:
use warnings;
use strict;
... my code changes and additions ...
no strict;
no warnings;
And that seems to work, but I'm having issues deciphering what the perldoc on use means when it says these are compiler directives that import into the current "block scope." Does that mean that any scope can have a use strict unpaired with a no strict? Is the no strict at the tail of the global scope essentially undoing the meaning of use strict earlier in the same scope?
"block scope" means both use strict; and no strict; have effect from where they are to the end of the innermost enclosing block, so no, a later no strict doesn't undo an earlier use strict. It just changes it for the innermost scope from that point in the code on. So:
{
use strict;
# strict in effect
{
# strict still in effect
no strict;
# strict not in effect
}
# strict in effect
no strict;
# strict not in effect
use strict;
# strict in effect
}
Which safety net do you use?
use warnings;
or
use strict;
I know that
A potential problem caught by use
strict; will cause your code to stop
immediately when it is encountered,
while use warnings; will merely give a
warning (like the command-line switch
-w) and let your code run.
Still I want to know that which one is mostly used by the Perl-programmers. Which one they have seen being used the most?
Both, of course. If perl were designed today, use strict and use warnings would be the default behavior. It's just like having warnings turned on in a compiler - why would you not do that by default?
What you have doesn’t even start to be enough.
I use code approximating this as a starting point. It works well in my environment, although as always your mileage may vary.
#!/usr/bin/env perl
use v5.12;
use utf8;
use strict;
use autodie;
use warnings;
use warnings qw< FATAL utf8 >;
use feature qw< unicode_strings >;
use open qw< :std :utf8 >;
use charnames qw< :full >;
# These are core modules:
use Carp qw< carp croak confess cluck >;
use File::Basename qw< basename dirname >;
use Unicode::Normalize qw< NFD NFKD NFC NFKC >;
use Getopt::Long qw< GetOptions >;
use Pod::Usage qw< pod2usage >;
our $VERSION = v0.0.1;
$0 = basename($0); # shorter messages
## $| = 1;
$SIG{__DIE__} = sub {
confess "Uncaught exception: #_" unless $^S;
};
$SIG{__WARN__} = sub {
if ($^S) { cluck "Trapped warning: #_" }
else { confess "Deadly warning: #_" }
};
END {
local $SIG{PIPE} = sub { exit };
close STDOUT;
}
if (grep /\P{ASCII}/ => #ARGV) {
#ARGV = map { decode("UTF-8", $_) } #ARGV;
}
binmode(DATA, ":utf8");
## Getopt::Long::Configure qw[ bundling auto_version ];
if (!#ARGV && -t STDIN) {
print STDERR "$0: reading from stdin: type ^D to end, ^C to kill...\n";
}
while (<>) {
$_ = NFD($_);
# ...
print NFC($_);
}
exit;
=pod
=encoding utf8
=head1 NAME
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 OPTIONS
=head1 EXAMPLES
=head1 ERRORS
=head1 FILES
=head1 ENVIRONMENT
=head1 PROGRAMS
=head1 AUTHOR
=head1 COPYRIGHT AND LICENCE
=head1 REVISION HISTORY
=head1 BUGS
=head1 TODO
=head1 SEE ALSO
=cut
__END__
Your UTF-8 data goes here.
You can find more examples of this sort of thing in action in the Perl Unicode Tool Chest, currently up to around 50 files ranging from the simple to the sublime.
use strict generates an error if you use symbolic references (ie, strings to represent names of symbols). It generates an error if you use a variable without declaring it (this encourages the use of lexical 'my' variables, but is also satisfied if you properly declare package globals). It also generates an error if you leave barewords hanging around in the script (unquoted strings, essentially, by Perl's definition of quotes). With 'strict', you may enable or disable any of three categories of strictures, and my do so within scoped blocks. It is a best practice to enable strictures, though on occasion legitimate code requires that some of its features be locally disabled. However, one should think long and hard about whether this is really necessary, and whether their solution is ideal. You can read about strictures in Perl's POD entitled 'strict'.
use warnings generates a warning message based on many criteria, which are described in the POD 'perllexwarn'. These warnings have nothing to do with strictures, but rather, watch for the most common "gotchas" one is likely to encounter in their programming. It is a best practice to use warnings while writing scripts too. In some cases where the message might be undesirable a certain warning category may be locally disabled within a scope. Additional info is described in 'warnings'.
use diagnostics makes the warnings more verbose, and in a development or learning environment, particularly among newcomers, that's highly desirable. Diagnostics would probably be left out of a 'final product', but while in development they can be a really nice addition to the terse messages normally generated. You can read about diagnostics in the Perl POD "diagnostics."
There is no reason to force oneself to use only one of the above options or another. In particular, use warnings and use strict should generally both be used in modern Perl programs.
In all cases (except diagnostics, which you're only using for development anyway), individual strictures or warnings may be lexically disabled. Furthermore, their errors may be trapped with eval{ .... }, with Try::Tiny's try/catch blocks, and a few other ways. If there's a concern about a message giving a potential attacker more information about a script, the messages could be routed to a logfile. If there's a risk of said logfile consuming lots of space, there's a bigger issue at hand, and the source of the issue should either be resolved or in some rare cases simply have the message disabled.
Perl programs nowadays should be highly strict/warnings compliant as a best practice.
Use both, as the linked page says.
The documentation is perhaps a bit unclear. use strict and use warnings catch different problems; use strict will not cause your program to immediately exit when mere warnings are encountered, only when you violate the strict syntax requirements. You will still get only warnings printed when your code does things that are less seriously bad.
use strict;
#use warnings;
use diagnostics; # "This module extends the terse diagnostics..." by http://perldoc.perl.org/diagnostics.html
Both! But I prefer diagnostics, instead of warnings, which give you some more information.
Iam new to perl and trying out a sample code for my project.
What happens when i write a code as given below to enable strict pragmas in perl.
use strict;
....... #Source Code
.......
no strict "vars";
....... #source code
use strict #do all strict pragmas enabled until the next pragma definition ?
......#Source Code
no strict "subs"; #do Only subs strict pragma is disabled and others enabled from here onwards?
...........
Can i embed use Strict Pragma declarations in between source code?
use strict is lexically scoped, which means it will stay in effect "until the end of the enclosing block, file, or eval (whichever comes first)."
For what it’s worth, I think it’s best to isolate the pragma changes using scope:
use strict;
{
no strict;
local $foo = 1;
}
local $bar = 1;
This blows up on setting bar, but not on foo.
From perldoc strict:
If no import list is supplied, all
possible restrictions are assumed.
You can change things to be strict about ("subs", "vars", and "refs") anytime.
I read in Simon Cozens' book "Beginning Perl" that -w switch for warnings would be deprecated going forward. Is this true or is it still ok to continue using -w rather than "use warnings".
The perlrun documentation (see perldoc perlrun or this page) indicates that the -w option is still available as of Perl 5.12.2. Using the pragma gets you nifty benefits though, like turning warnings on lexically and finer grained warnings.
Here is a blurb on why you should use the pragma instead of the command line option.
The -w option will NOT go away!
The preferred method of turning on warnings is use warnings because -w has a global effect. (In fact, -w is implemented by means of a global variable $^W. That alone should tell you that the lexical version is safer.)