5

我正在使用Perl 的Safe模块中的reval,如果无法解析正在评估的字符串,我想阻止它生成警告(实际上,我想阻止它生成任何警告)。

例如,下面的代码:

use strict; use warnings;
use Safe;    
use feature qw/say/;
my $cft = Safe->new;

my $x = $cft->reval(') 1' );
my $y = $cft->reval('2'   );
say "x: $x";
say "y: $y";

结果是:

Number found where operator expected at (eval 5) line 1, near ") 1"
    (Missing operator before 1?)
Use of uninitialized value $x in concatenation (.) or string at ./test line 12.
x: 
y: 2

我想要实现的是让 $x = undef 和 $y = 2,并且没有警告。我试图提出“没有警告;” 在新范围内,但它对 reval 内产生的警告没有影响(尽管正如@DavidO 所指出的,它使“未初始化值”警告静音):

use strict; use warnings;
use Safe;    
use feature qw/say/;
my $cft = Safe->new;
{
    no warnings;
    my $x = $cft->reval(') 1' );
    my $y = $cft->reval('2'   );
    say "x: $x";
    say "y: $y";
}

我想不知何故,“无警告”必须在保险箱内,所以我也尝试在“无警告”前面加上“无警告”;到被评估的字符串:

use strict; use warnings;
use Safe;
use feature qw/say/;
my $cft = Safe->new;
{
    my $x = $cft->reval( 'no warnings;' . ') 1' );
    my $y = $cft->reval( 'no warnings;' . '2'   );
    say "x: $x";
    say "y: $y";
}

这样 reval 不会发出任何警告,但两个变量都是 undef:

Use of uninitialized value $x in concatenation (.) or string at ./test line 10.
x: 
Use of uninitialized value $y in concatenation (.) or string at ./test line 11.
y:

我不知道还有什么可以尝试的,我希望问题描述足够清楚。

4

2 回答 2

4

no warnings禁止use warnings编译指示生成的所有警告。您可能还想删除任何strict尿素。但是严重的解析错误会以任何方式弹出。

如果你想执行任何代码,无论多么病态,没有任何输出到 STDERR,你应该在本地修改信号处理程序:

{
  # I know what I'm doing!
  local $SIG{__WARN__} = sub {}; # locally ignore any warnings
  eval $code; # catches all "die"
}

或者我们可以重新STDERR打开/dev/null

{
  # I know what I'm doing!
  open my $oldSTDERR, '>&' \*STDERR or die;
  close STDERR or die;
  open STDERR, '>', '/dev/null' or die;

  eval $code;

  close STDERR or die;
  open STDERR, '>&', $oldSTDERR or die;
  close $oldSTDERR;
}
于 2012-07-26T20:46:58.130 回答
4

如果你检查$@你会看到$cft->reval( 'no warnings;' . ') 1' );失败。 'require' trapped by operation mask at (eval 5) line 1.. 换句话说,Safe 正在完成它的工作并阻止该代码尝试加载库。

$cft->reval( 'BEGIN { warnings->unimport; } ) 1' );会起作用,假设警告已经加载到隔间外。但是,这不会消除编译时错误。不像evalreval似乎让他们通过。使用 amon 的静默 STDERR 技术。

于 2012-07-26T21:25:16.830 回答