考虑以下包装器函数,如果函数抛出(不确定为什么格式化不稳定),则会给定函数重试一定次数:
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;
}
如何扩展,以便无论返回什么类型的值,都可以正确地调整参数函数的返回值?例如,此函数不会正确传递数组。你不能只返回$ fun->()因为返回只会让你离开eval块。
答案 0 :(得分:6)
与Nemo相同的基本答案,但有一些改进:
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->(@_);
}
Void上下文作为void上下文传播,但这可能是可以接受的。如果没有,它很容易调整。
答案 1 :(得分: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;
}
我确信一个怪物Perl黑客可以找到一种方法来收紧它,但这是基本的想法。