我正在使用Perl的reval模块中的Safe,如果无法解析被评估的字符串,我想阻止它生成警告(实际上,我想阻止它生成任何警告都可以。)
例如,以下代码:
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:
我不知道还有什么可以尝试,我希望问题描述足够清楚。
答案 0 :(得分:4)
no warnings
会抑制use warnings
pragma生成的所有警告。您可能还想删除任何strict
ures。但是会出现严重的解析错误。
如果你想执行任何代码,无论多么病态,没有任何输出到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;
}
答案 1 :(得分:4)
如果您选中$@
,则会看到$cft->reval( 'no warnings;' . ') 1' );
失败。 'require' trapped by operation mask at (eval 5) line 1.
。换句话说,Safe正在完成其工作并阻止该代码尝试加载库。
$cft->reval( 'BEGIN { warnings->unimport; } ) 1' );
可以正常工作,假设警告已经加载到隔间外。但是,这不会安静编译时错误。与eval
不同,reval
似乎让他们通过。使用amon安静STDERR的技术。