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

Mat*_*ick 1 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();
Run Code Online (Sandbox Code Playgroud)

这是我的测试输出(当使用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.
Run Code Online (Sandbox Code Playgroud)

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

Axe*_*man 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 $@;
    
    Run Code Online (Sandbox Code Playgroud)