English 中文(简体)
采用以下方式执行次路线的回历逻辑: 企图
原标题:implementing retry logic for subroutine using Sub::Attempts
  • 时间:2012-01-13 21:21:54
  •  标签:
  • perl

重提我的问题。

Sub::Attempts retries once it find the exception (die). For me, I want the sub to retry when sub is returning the false value.

让我知道,我应做些什么来改变工作?

最佳回答

If you want to use Sub::Attempts, just make a subroutine that modifies the one you have to make it die rather than return 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;
   }
}

The goto &sub form will throw out local lexical variables, and start the subroutine over again, but it is susceptible to any changes you may have made to @_:

sub foo {
   my $x = shift @_;
   if ($x < 5) {
       @_ = ($x + 1);
       goto &foo;
   }
   return $x;
}

print &foo;
__END__
5

<代码>return &foo(@_)和goto &foo之间的差别在于:goto 版本在打字栏上添加了字体——例如尾再保险优化。

或者,你可以让我们简单地::

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;
}

to call worker functions (not exactly) like

sub s00 {
  my $r = 0.2 > rand() ?  ok  :  fail ;
  print    in s00 =>  , join(  - , @_, $r), "
";
  return $r;
}

sub s01 {
  my $r = 0.5 < rand() ?  ok  :  fail ;
  print    in s01 =>  , join(  - , @_, $r), "
";
  return $r;
}

缩略语

  print  from s00 =>  , s00(1, 2, 3), "
";
  print  from s01 =>  , s01(qw/a b/), "
";

  print  from rpw =>  , rpw(&s00, 5, 1, 2, 3), "
";
  print  from rpw =>  , rpw(&s01, 5, qw/a b/), "
";

产出(而不是 l):

  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

with:

  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




相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签