【问题标题】:in perl, 'use strict' disables important warnings在 perl 中,'use strict' 禁用重要警告
【发布时间】: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 stricteval 将失败,并且不会打印任何警告。
  • 你为什么使用eval?这里完全没有必要。
  • 不要在子声明中使用空括号,它不会添加您需要的任何内容,并且它不像其他语言那样工作。子声明中的括号用于添加原型,旨在帮助子例程像某些内置函数一样工作。 (例如map { ... } @listpush @array, $value。)

标签: perl


【解决方案1】:

它不是警告,而是抛出异常。而且您不是在测试 eval 是否给出了异常。

试试:

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

【讨论】:

  • 谢谢,我了解到在使用eval 时需要明确检查错误。 (我仍然认为use strict 导致警告消失很奇怪,但我知道这是因为eval 有一种特殊的报告错误的方式。
  • 在对未定义的值进行字符串化时会出现警告,但使用 strict 会在 eval 编译 $rule 时,甚至在它开始替换搜索之前就死掉
猜你喜欢
  • 2012-02-15
  • 2015-05-13
  • 2020-12-07
  • 2014-01-17
  • 2010-12-05
  • 1970-01-01
  • 2015-10-19
  • 2016-12-15
相关资源
最近更新 更多