刷新我的问题。
Sub :: Attempts一旦找到异常(die)就重试。 对我来说,当sub返回false值时,我希望sub重试。
请让我知道我应该改变什么才能让它发挥作用?
答案 0 :(得分:1)
如果你想使用Sub::Attempts
,只需创建一个子程序来修改你必须使其死亡的子程序,而不是返回false:
sub die_on_failure {
my $name = (caller).'::'.shift;
my $glob = do {no strict 'refs'; \*$name};
my $code = \&$glob;
no warnings 'redefine';
*$glob = sub {
my $ret = &$code;
$ret ? $ret : die "$name failed"
}
}
然后就这样做:
die_on_failure 'your_sub_name';
致电之前:
attempts 'your_sub_name', ...;
答案 1 :(得分:0)
sub retryBeforeFail {
my $className = shift;
my $attempt = shift;
my $max = shift;
my $success = 0;
... main code here ...
if (!$success && $attempt < $max) {
$attempt++;
return $self->retryBeforeFail($attempt, $max);
} else {
return $success;
}
}
答案 2 :(得分:0)
听起来你需要一个循环,某种形式。解决这个问题的一种方法是简单的“全部完成”标志:
sub foo {
my $success = undef;
until ($success) {
# do something interesting
redo if $something_failed;
# do more things here
++$success; # if it all worked properly
# or, exit early on success:
return $something if $all_is_well;
}
}
如果不使用临时var和until
循环,您还可以使用goto &subroutine
的特殊形式重新启动子资源:
sub foo {
# do something interesting
if ($something_failed) {
goto &foo;
}
}
goto &sub
表单将抛出本地词法变量,并重新启动子例程,但 容易受到@_
所做的任何更改:< / p>
sub foo {
my $x = shift @_;
if ($x < 5) {
@_ = ($x + 1);
goto &foo;
}
return $x;
}
print &foo;
__END__
5
return &foo(@_)
和goto &foo
之间的区别在于goto
版本没有添加到调用堆栈 - 有点像尾递归优化。
答案 3 :(得分:0)
或者你可以让我们一个简单的循环:
sub retry_before_fail {
my ( $maxtries , $coderef , @args ) = @_ ;
while( $maxtries ) {
# $coderef returns non zero upon success
if( my $result = $coderef->( @args ) ) {
return $result ;
}
$maxtries-- ;
}
# Failure now either return or die
return ;
}
答案 4 :(得分:0)
如果你有大约60个潜艇,你可以使用包装器功能(从HOP偷来的想法) - 就像这样:
sub rpw {
my $f = shift;
my $t = shift;
my $r = &$f(@_);
while ('fail' eq $r && --$t) {
$r = &$f(@_);
}
return $r;
}
调用'worker'函数(不完全像)
sub s00 {
my $r = 0.2 > rand() ? 'ok' : 'fail';
print ' in s00 => ', join( '-', @_, $r), "\n";
return $r;
}
sub s01 {
my $r = 0.5 < rand() ? 'ok' : 'fail';
print ' in s01 => ', join( '-', @_, $r), "\n";
return $r;
}
来自主要代码,如
print 'from s00 => ', s00(1, 2, 3), "\n";
print 'from s01 => ', s01(qw/a b/), "\n";
print 'from rpw => ', rpw(\&s00, 5, 1, 2, 3), "\n";
print 'from rpw => ', rpw(\&s01, 5, qw/a b/), "\n";
输出(不幸运):
in s00 => 1-2-3-fail
from s00 => fail
in s01 => a-b-fail
from s01 => fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
from rpw => fail
in s01 => a-b-fail
in s01 => a-b-ok
from rpw => ok
运气不错:
in s00 => 1-2-3-ok
from s00 => ok
in s01 => a-b-fail
from s01 => fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-fail
in s00 => 1-2-3-ok
from rpw => ok
in s01 => a-b-fail
in s01 => a-b-fail
in s01 => a-b-ok
from rpw => ok