Perl Can';使用严格的';警告而不是错误

Perl Can';使用严格的';警告而不是错误,perl,error-handling,strict,Perl,Error Handling,Strict,使用use strictperl时,会在不安全的构造上生成运行时错误。现在我想知道是否有可能让它只打印一个警告,而不是导致运行时错误?或者use warnings(或-w)警告相同的问题吗?否,use strict不能发出警告而不是死亡。它所做的只是在magic$^H变量中设置一些位,这会触发Perl解释器内部的各种事情 不,use warnings与use strict的警告不一样。例如,use warnings将警告您只使用了一次变量(这可能是打字错误造成的)。首选方法: use Carp;

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

否,
use strict
不能发出警告而不是死亡。它所做的只是在magic
$^H
变量中设置一些位,这会触发Perl解释器内部的各种事情

不,
use warnings
use strict
的警告不一样。例如,
use warnings
将警告您只使用了一次变量(这可能是打字错误造成的)。

首选方法:

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
并搜索
/\$\@/
/\uuu DIE\uuu/


perldoc-Carp

警告和
strict
杂注是互补的,而不是重叠的。
strict
pragma同时具有编译时和运行时效果。您不能将限制的严重性从错误降低到警告,但可以完全禁用它们。例如,如果您正在编写自己的导出例程,则需要启用符号引用以操作符号表

{
    no strict 'refs';
    # symrefs okay within this block
}
还可以按词汇禁用警告(假设您使用了
警告
,而不是基本上过时的
-w
标志)


限制和警告提供了一个安全网。这就是为什么建议在默认情况下使用它们。如果禁用它们,则应仅禁用必要的内容,并将更改限制在尽可能小的范围内。

警告可以设置为致命-请参阅-但严格的错误不能设置为非致命


你为什么要这么做?我怀疑是XY问题。

我要试着猜一下这里的真正动机。如果我猜错了,请随时告诉我

我怀疑您试图处理一个大型的、较旧的代码库,并且希望启用严格限制,但您希望首先能够在不破坏功能的情况下了解错误的位置(以及错误的数量)。不幸的是,由于
通过修改perl解析器和解释器的内部行为来使用strict
函数,因此没有“松散严格”模式,或者类似于html,没有任何类型的“过渡”模式

但是,您可以梳理
的功能,使用strict
开始朝正确的方向移动。首先,请注意,实际上有三个独立的部分:

use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords
其中只有“refs”会生成运行时错误。因此,您可以轻松地向每个文件(脚本和模块)添加
使用严格的qw(vars subs)
,并使用
perl-c
测试它们。如果遇到任何错误消息,请注释掉
使用strict
,或至少注释两个检查中失败的一个,并添加有关失败性质的注释,然后继续。通过这种方式,您可以快速(取决于文件的数量)确定哪些文件存在编译时错误,并在以后返回解决这些错误。(如果你当时比我更有动力,你甚至可以自动化这个过程)。除非您的代码在
BEGIN
块中执行可怕的操作,否则这样做应该是非常安全的

更棘手的部分是检查由
使用严格的“refs”
生成的运行时错误,不幸的是,这并不是一个简单的方法,因为错误是由符号引用触发的,而符号引用不能由任何类型的静态分析确定,所以-c和/或两者都是无用的


希望这能更接近于解决您真正的问题。

您为什么需要这样做?如果必须使用
no strict,则可以对部分代码禁用strict。原因是我使用的是不允许停止的生产关键代码库。同时,我想一次解决一个问题。在这种情况下,通过发出警告并检查完整日志,而不是:*查找中止的运行*修复问题*重新运行*等待几个小时,直到下一个问题的at中止,等等…这将如何避免由“严格使用”引起的运行时错误?请参阅主问题下的注释;基本上,我想慢慢过渡到使用strict。允许当前代码立即中止这些严格错误不是一个选项。@Zitrax,然后慢慢添加
use strict(或慢慢删除
无严格限制;
)。忽略警告没有任何好处。谢谢,你的猜测完全正确。我现在不能只允许在这段代码中出现运行时错误,但我确实希望最终使用strict。使用“perl-c”进行检查已经到位,因此跳过refs将是很好的第一步。