Reputation: 5555
I’m working on a Perl CGI script about 4000 lines big. Our coding style includes use strict
and use warnings
usually, but in this particular (quite old) file, "use warnings" is commented out, with the comment stating that enabling warnings would flood the Apache log.
Now I plan to separate some code into a new subroutine. I want to use warnings
at least there. How can I safely limit the effect of use warnings
to one subroutine? Will just placing the use
clause inside the subroutine do the job?
Upvotes: 4
Views: 281
Reputation: 67900
The answer that use warnings
can be used lexically is correct. The solution to use no warnings
lexically and use warnings
globally is more correct. The correctest solution is to fix all your warnings. Somewhere in between lies redirecting the errors.
use warnings;
open STDERR, ">>", "foo/error.log" or die $!;
Leave that up for a while, then run:
perl -nlwe '$a{$_}++ }{ print for keys %a' foo/error.log > foo/errors.dedupe
Go through the code and fix the warnings. Most likely, if the script is working, they will be trivial. But unless you check, how do you know?
If in the end you decide that its not worth the hassle to fix all the warnings, then just remove the warnings and error redirection and use warnings lexically.
Upvotes: 2
Reputation: 63797
Yes, the use of use warning
will be in the scope in which you have written it.
Writing use warning
inside a sub will only affect the giving routine (or block).
example snippet
sub foo {
use warnings;
print my $a;
}
{
use warnings;
print my $b;
}
foo;
print my $c;
output
Use of uninitialized value $b in print at foo.pl line 8.
Use of uninitialized value $a in print at foo.pl line 3.
Note that no warning is thrown about the use of print my $c
.
What does the documentation say?
This pragma works just like the strict pragma. This means that the scope of the warning pragma is limited to the enclosing block. It also means that the pragma setting will not leak across files (via use, require or do). This allows authors to independently define the degree of warning checks that will be applied to their module.
Upvotes: 13
Reputation: 2847
Turning on warnings globally, then turning it off for specific sections sounds like a good plan.
You don't have to put use warnings;
or no warnings;
inside every sub
. You can make ad-hoc scopes using braces, eg.
use warnings;
sub nice_new_sub_1 { ... }
sub nice_new_sub_2 { ... }
{
no warnings;
sub nasty_old_sub_3 { ... }
sub nasty_old_sub_4 { ... }
sub nasty_old_sub_5 { ... }
}
Also, consider turning off only those warnings you need to make it work cleanly, e.g.
{
no strict 'refs';
sub nasty_old_sub_3 { ... }
sub nasty_old_sub_4 { ... }
}
Upvotes: 2
Reputation: 69244
Yes, as other people have pointed out. But, in my opinion, you would be better advised to turn on warnings globally and just turn them off around problematic sections of code.
use warnings;
sub new_method {
# shiny new code
}
sub old_method {
no warnings;
# nasty old code
}
Upvotes: 4
Reputation: 6872
Yes. From the perldoc:
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.
http://perldoc.perl.org/warnings.html
Upvotes: 3
Reputation: 5555
Just found the answer myself in "perldoc perllexwarn":
...the scope of the warning pragma is limited to the enclosing block.
So the following should work:
sub new_method {
use warnings;
...
}
sub old_method {
... # no warnings here
}
Upvotes: 2