【发布时间】:2016-07-11 10:38:04
【问题描述】:
将use strict 添加到 perl 程序会禁用重要的警告消息。这是 perl 中的错误吗?
这个小程序有问题
#!/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";
在运行该程序时我们会收到一条有用的警告消息:
$ ./test1.pl
Use of uninitialized value $foo_bar in substitution (s///) at (eval 1) line 1.
OUTPUT: Please replace with something.
现在添加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";
替换只是默默地失败了。
$ ./test1.pl
OUTPUT: Please replace #FOO_BAR with something.
当我在 perl 中出现神秘错误时,我是否应该总是尝试删除 use strict 以查看是否会收到一些有用的警告?
edit 1 stackoverflow 要求我描述为什么这不是 Why use strict and warnings? 的副本。在这种情况下,添加use strict 会导致更少的警告,这使得调试更加困难——这与我期望use strict 会做的相反;与该问题的答案中建议的相反:
pragma 会比其他方式更快地捕获到许多错误,从而更容易找到错误的根本原因。
edit 2:对于其他看到此内容的人:另一种方式是:
defined (eval $rule) or warn "eval error: $@\n";
因为如果有错误,eval 会返回 undefined。 Programming Perl 一书在关于 eval 的部分中指出
如果存在语法错误或运行时错误,eval 将返回未定义的值并将错误消息放在 $@ 中。如果没有错误,保证 $@ 被设置为空字符串,因此您可以在之后可靠地测试它是否有错误。
但请注意with versions prior to Perl 5.14 there can be problems relying on '$@`。
【问题讨论】:
-
short: 添加“使用警告‘全部’;”改进脚本。
-
如果省略
use strict,使用未声明的变量不会导致编译失败。所以eval会成功,但会打印一个警告。如果包含use strict,eval将失败,并且不会打印任何警告。 -
你为什么使用
eval?这里完全没有必要。 -
不要在子声明中使用空括号,它不会添加您需要的任何内容,并且它不像其他语言那样工作。子声明中的括号用于添加原型,旨在帮助子例程像某些内置函数一样工作。 (例如
map { ... } @list或push @array, $value。)
标签: perl