简体   繁体   中英

in perl, 'use strict' disables important warnings

Adding use strict to a perl program disables an important warning message. Is this a bug in perl?

This little program has a problem

#!/usr/bin/perl -w
my $rule;
sub applyRule() {
    eval $rule;
}
my $foo_bar;
$foo_bar = "mega-foo-bar-ness";
$rule = 's/#FOO_BAR/$foo_bar/g';
$_ = "Please replace #FOO_BAR with something.";
applyRule();
print STDERR "OUTPUT: $_\n";

and we get a helpful warning message when running that program:

$ ./test1.pl
Use of uninitialized value $foo_bar in substitution (s///) at (eval 1) line 1.
OUTPUT: Please replace  with something.

Now add use strict;

#!/usr/bin/perl -w
use strict;
my $rule;
sub applyRule() {
    eval $rule;
}
my $foo_bar;
$foo_bar = "mega-foo-bar-ness";
$rule = 's/#FOO_BAR/$foo_bar/g';
$_ = "Please replace #FOO_BAR with something.";
applyRule();
print STDERR "OUTPUT: $_\n";

The substitution just silently fails.

$ ./test1.pl
OUTPUT: Please replace #FOO_BAR with something.

When I have mysterious errors in perl should I always try removing use strict to see if I get some helpful warnings?

edit 1 stackoverflow is asking me to describe why this is not a duplicate of Why use strict and warnings? . This is a case where adding use strict results in fewer warnings, which makes debugging harder -- the opposite of what I expect use strict would do; the opposite of what is suggested in the answers to that question:

The pragmas catch many errors sooner than they would be caught otherwise, which makes it easier to find the root causes of the errors.

edit 2 : For anyone else seeing this: another way is:

defined (eval $rule) or warn "eval error: $@\n";

because eval returns undefined if there is an error. The Programming Perl book states in the section about eval

If there is a syntax error or run-time error, eval returns the undefined value and puts the error message in $@. If there is no error, $@ is guaranteed to be set to the null string, so you can test it reliably afterward for errors.

Note however that with versions prior to Perl 5.14 there can be problems relying on '$@` .

Instead of a warning, it throws an exception. And you aren't testing to see if eval gave an exception.

Try:

eval "$rule; 1" or warn "exception thrown: $@\n";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM