刷新我的問題,實現子程序的重試邏輯。使用Sub :: Attempts
Sub ::一旦發現異常(死亡),嘗試重試。 對於我來說,我希望sub在sub返回false值時重試。
請讓我知道我應該改變什麼才能使它工作?
刷新我的問題,實現子程序的重試邏輯。使用Sub :: Attempts
Sub ::一旦發現異常(死亡),嘗試重試。 對於我來說,我希望sub在sub返回false值時重試。
請讓我知道我應該改變什麼才能使它工作?
如果你想使用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', ...;
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;
}
}
聽起來像你需要一個循環,某種。要解決這個問題的一個方法是一個簡單的「全部完成」標誌:
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;
}
}
,不使用臨時變量和until
循環,您還可以使用goto &subroutine
特殊形式重新啓動子:
sub foo {
# do something interesting
if ($something_failed) {
goto &foo;
}
}
的goto &sub
形式將拋出本地詞法變量,並重新開始的子程序,但它是容易,你可能已經到@_
所做的任何更改:
sub foo {
my $x = shift @_;
if ($x < 5) {
@_ = ($x + 1);
goto &foo;
}
return $x;
}
print &foo;
__END__
5
return &foo(@_)
和goto &foo
之間的區別,在於goto
版本不添加到調用堆棧 - 有點像尾遞歸優化。
,或者你可以我們一個簡單的while循環:
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 ;
}
如果您有關於60潛艇,你可以使用一個包裝函數(想法來自HOP被盜) - 這樣的:
sub rpw {
my $f = shift;
my $t = shift;
my $r = &$f(@_);
while ('fail' eq $r && --$t) {
$r = &$f(@_);
}
return $r;
}
叫 '工人' 功能(恰好沒有)像
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