这个perl包装函数可以扩展为使用任何输入函数吗?

fra*_*nkc 3 perl eval

考虑下面的包装器函数,如果函数抛出(不确定为什么格式化不稳定),它会在给定次数内重试给定函数:


sub tryit{
    my $fun = shift;
    my $times = shift;
    my @args = @_;
    my $ret;
    do{  
    $times--;
    eval{
        $ret = $fun->(@args);
    };
    if($@){
        print "Error attemping cmd: $@\n";
    }
    else{
         return $ret;
    }
    }while($times > 0);
    return;

}
Run Code Online (Sandbox Code Playgroud)

如何扩展,以便无论返回什么类型的值,都可以正确地调整参数函数的返回值?例如,此函数不会正确传递数组.你不能只返回$ fun - >()因为返回只会让你退出eval块.

ike*_*ami 6

与Nemo相同的基本答案,但有一些改进:

  • 更安全的异常处理.
  • 没有抓住最后一次尝试的例外.
  • 发送到STDERR时出错.
  • 删除了额外的换行符.
  • 清洁循环.
  • 更好的变量名称.

wantarray 将为您提供所需的信息.

sub tryit {
    my $func        = shift;
    my $attempts    = shift;
    my $list_wanted = wantarray;
    my @rv;
    for (2..$attempts) {
        if (eval{
            if ($list_wanted) {
                @rv = $func->(@_);
            } else {
                $rv[0] = $func->(@_);
            }
            1  # No exception
        }) {
            return $list_wanted ? @rv : $rv[0];
        }

        warn($@, "Retrying...\n");
    }

    return $func->(@_);
}
Run Code Online (Sandbox Code Playgroud)

Void上下文作为void上下文传播,但这可能是可以接受的.如果没有,它很容易调整.


Nem*_*emo 5

你可以用wantarray做到这一点.(对我来说格式也很糟糕;对不起)

sub tryit{
    my $fun = shift;
    my $times = shift;
    my @args = @_;
    my $array_wanted = wantarray;
    my $ret;
    my @ret;
    do{  
    $times--;
    eval{
        if ($array_wanted) {
            @ret = $fun->(@args);
        }
        else {
            $ret = $fun->(@args);
        }
    };
    if($@){
        print "Error attemping cmd: $@\n";
    }
    else{
         if ($array_wanted) {
             return @ret;
         }
         else {
             return $ret;
         }
    }
    }while($times > 0);
    return;

}
Run Code Online (Sandbox Code Playgroud)

我相信一个怪物Perl黑客可以找到一种方法来收紧它,但这是基本的想法.

  • 如果你想成为邪恶的,你可以将`$ ret`更改为`$ ret [0]`并完全删除标量`$ ret`变量.此外,您可能想要考虑`wantarray`返回`undef`的场景. (2认同)
  • `$ list_wanted`是`wantarray`返回的内容.如果你不使用`$ wantarray`来保持一致性,那么也可以使用正确的术语.函数返回数组是不可能的. (2认同)