可以'使用严格'警告而不是错误

时间:2011-03-25 10:33:04

标签: perl error-handling strict

使用use strict perl会在不安全的构造上生成运行时错误。现在我想知道是否可以让它只打印警告而不是导致运行时错误?或use warnings(或-w)警告同样的问题?

5 个答案:

答案 0 :(得分:14)

不,use strict不能发出警告而不是死亡。它所做的就是在魔术$^H变量中设置几个位,这会触发Perl解释器的内容中的各种内容。

不,use warnings没有警告与use strict杀死你的事情相同的事情。例如,use warnings将警告您仅使用一次的变量(这可能是拼写错误的结果)。

答案 1 :(得分:4)

warningsstrict 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问题。