Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么这两个分支似乎都执行?_Perl_Eval - Fatal编程技术网

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:是的,