为什么两个分支似乎都执行?

时间:2012-03-14 20:05:33

标签: 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();

这是我的测试输出(使用ActivePerl 5.12,Mac OS X运行时):

    not ok 1 - only execute one branch (i: 2)
    #   Failed test 'only execute one branch (i: 2)'
    #   at test.pl line 14.
    #          got: '2'
    #     expected: '1'
    1..1
    # Looks like you failed 1 test of 1.
not ok 1 - huh?
#   Failed test 'huh?'
#   at test.pl line 15.
1..1
# Looks like you failed 1 test of 1.

这里发生了什么?我预计只有第一个分支才能运行,因为没有die。但看起来两个分支都被执行了。

2 个答案:

答案 0 :(得分:5)

$i++在增量之前返回$i 的值。所以既然是0,那就错了。 eval返回最后评估的结果,即false值。然后继续尝试下一个块(应该如此)。

如果您只希望获取第一个分支,则需要将增量表达式“增量,然后返回”,如此eval { ++$i }

现在,查看eval失败的最佳方法是不返回1,而是执行以下操作:

  1. 本地化$@(或$English::EVAL_ERROR
  2. EVAL
  3. 测试$@

    local $@;
    eval { $some_sub->(); };
    croak( "Failed in evaluate: $@" ) if $@;
    

答案 1 :(得分:2)

eval { $i ++ }返回$i ++返回的相同结果,即$i在递增之前的值。由于您将$i设置为0,因此返回0,这是假的,这意味着||的右操作数也会被评估。

我认为你将{{1>}的结果返回混淆了(这只是包含表达式的结果),结果为eval {{1} },保存在die