Perl 为什么这两个分支似乎都执行?
我完全糊涂了。这是我的密码:Perl 为什么这两个分支似乎都执行?,perl,eval,Perl,Eval,我完全糊涂了。这是我的密码: use strict; use warnings; use Test::More; subtest 'huh?' => sub { my $i = 0; eval { $i++; } || do { $i++; }; is($i, 1, "only execute one branch (i: $i)"); }; &done_testing(); 下面是我的测试输出(在使用A
use strict;
use warnings;
use Test::More;
subtest 'huh?' => sub {
my $i = 0;
eval {
$i++;
} || do {
$i++;
};
is($i, 1, "only execute one branch (i: $i)");
};
&done_testing();
下面是我的测试输出(在使用ActivePerl 5.12、Mac OS X运行时):
这是怎么回事?我只希望第一个分支运行,因为没有任何东西
die
s。但看起来两个分支都已执行。$i++
返回增量之前的$i
值。既然它是0,那么它就是假的。和eval
返回最后一个计算结果,即假值。然后它继续尝试下一个块(它应该这样做)
如果只希望它执行第一个分支,则需要生成增量表达式“increment,then return”,如下eval{++$i}
现在,查看eval
是否失败的最佳方法不是返回1,而是执行以下操作:
$@
(或$English::EVAL_ERROR
)$@
local $@;
eval { $some_sub->(); };
croak( "Failed in evaluate: $@" ) if $@;
$i++
返回增量之前的$i
值。既然它是0,那么它就是假的。和eval
返回最后一个计算结果,即假值。然后它继续尝试下一个块(它应该这样做)
如果只希望它执行第一个分支,则需要生成增量表达式“increment,then return”,如下eval{++$i}
现在,查看eval
是否失败的最佳方法不是返回1,而是执行以下操作:
$@
(或$English::EVAL_ERROR
)$@
local $@;
eval { $some_sub->(); };
croak( "Failed in evaluate: $@" ) if $@;
eval{$i++}
返回与$i++
返回的结果相同的结果,即$i
在递增之前的值。由于将$i
设置为0
,因此它返回0
,这是false,这意味着|
的右操作数也会被计算
我认为您混淆了
eval
返回的结果(这只是包含表达式的结果)与eval
中die
的结果,后者保存在$@
eval{$I++}
中,返回的结果与$I++
返回的结果相同,即,$i
在递增之前的值。由于将$i
设置为0
,因此它返回0
,这是false,这意味着|
的右操作数也会被计算
我认为您将
eval
返回的结果(这只是包含表达式的结果)与eval
中die
的结果相混淆,后者保存在$@
啊。。。因此,当我使用eval
捕获异常时,我应该始终确保它返回一个真值,以防eval
中没有抛出异常?@MattFenwick,如果您要用|
或测试返回,那么是的。我将更新我的答案。如果您在修复错误之前正在运行perl版本,$@
可以在销毁
块中清除,然后If$@
语句才有机会运行<代码>eval{…;1}或croak…
不会受到该错误的影响。啊。。。因此,当我使用eval
捕获异常时,我应该始终确保它返回一个真值,以防eval
中没有抛出异常?@MattFenwick,如果您要用|
或测试返回,那么是的。我将更新我的答案。如果您在修复错误之前正在运行perl版本,$@
可以在销毁
块中清除,然后If$@
语句才有机会运行eval{…;1}或croak…
没有受到该错误的影响。是的,我想我必须重构我的代码库以检查$@
而不是eval
的返回值@briandfoy:是的,是的,我想我必须重构我的代码库来检查$@
而不是eval
@briandfoy:是的,