使用use strict
perl会在不安全的构造上生成运行时错误。现在我想知道是否可以让它只打印警告而不是导致运行时错误?或use warnings
(或-w)警告同样的问题?
答案 0 :(得分:14)
不,use strict
不能发出警告而不是死亡。它所做的就是在魔术$^H
变量中设置几个位,这会触发Perl解释器的内容中的各种内容。
不,use warnings
没有警告与use strict
杀死你的事情相同的事情。例如,use warnings
将警告您仅使用一次的变量(这可能是拼写错误的结果)。
答案 1 :(得分:4)
warnings
和strict
pragma是互补的,不重叠。 strict
pragma具有编译时和运行时效果。您无法将限制的严重性从错误降低到警告,但您可以完全禁用它们。例如,如果您正在编写自己的导出例程,则需要启用符号引用以操作符号表。
{
no strict 'refs';
# symrefs okay within this block
}
也可以在词汇上禁用警告(假设您执行了use warnings
而不是过时的-w
标记)。
限制和警告提供安全网。这就是为什么他们建议默认使用它们。如果禁用它们,则应仅禁用所需的内容,并将更改限制为尽可能小的范围。
答案 2 :(得分:4)
我会在这里猜测真正的动机。如果我猜错了,请随时告诉我。
我怀疑你试图解决一个庞大的旧代码库,并希望启用限制但是你希望首先了解错误的位置(以及有多少)而不破坏功能。不幸的是,由于use strict
通过修改perl解析器和解释器的内部行为来起作用,因此没有“松散严格”或类似于html的任何类型的“过渡”模式。
但是,您可以将use strict
的功能分开以开始向正确的方向移动。首先,请注意实际上有三个独立的部分:
use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords
而那些只有'refs'会产生运行时错误。因此,您可以轻松地将use strict qw(vars subs)
添加到每个文件(脚本和模块)中,并使用perl -c
对其进行测试。如果您遇到任何错误消息,请注释掉use strict
,或至少两个检查失败中的任何一个,并添加关于失败性质的注释并继续。这样,您可以快速(取决于文件的数量)确定哪些文件具有编译时错误,然后返回以解决它们。 (如果你现在比我更有动力,你甚至可以自动化这个过程)。除非你的代码在BEGIN
块内部做了可怕的事情,否则这应该是非常安全的。
更棘手的部分是检查use strict 'refs'
生成的运行时错误,遗憾的是,确实没有一种简单的方法可以做到这一点,因为错误是由符号引用触发的,无法通过任何类型确定静态分析所以-c和/或Perl::Critic都没用。
希望能更接近解决您的真实问题。
答案 3 :(得分:3)
首选方法:
use Carp;
sub foo {
croak "no args" unless @_;
}
eval foo();
if( $@ ){
print "caught die: $@";
}
如果您无法将die
改为croak
:
sub foo {
die "no args" unless @_;
}
{
my $prev_die = $SIG{__DIE__};
$SIG{__DIE__} = sub { print "caught die: $_[0]"; };
eval foo();
$SIG{__DIE__} = $prev_die;
}
第二种方法将在STDERR上打印出错误。
请参阅:
perldoc -f eval
perldoc perlvar
并搜索/\$\@/
和/__DIE__/
perldoc Carp
答案 4 :(得分:1)
警告可能会致命 - 请参阅perllexwarn - 但严格的错误不能成为非致命错误。
你为什么要这样做?我怀疑是XY问题。