in reply to How do I use a block as an ‘or’ clause instead of a simple die?

Problem #1: You have an "or" statement, not a subroutine block therefore a return(-1) is nonsense...return -1 to where and to whom?

I snipped out some code from one of my LWP programs. This will show you how to do a retry. In my application, a retry is required about 1/2,500 or so requests. Ok let's say that just one of 1,000 attempts fail...that's still a small number but if I am gonna run 10,000 requests, that is gonna happen on most of the runs and in this case a retry almost always works, so I don't want to "die". First some code, then some discussion:

#!/usr/bin/perl -w use strict; use constant MAX_RETRY => 2; my $ua = LWP::UserAgent->new; my $raw_html; my $someParam; RETRY: while (my $n_attempt=0, $someParam=<IN>) { #...some clean up of $someParam my $req = POST 'http://www.someURL/db/', [ action => '/db/', dbparam => "$someParam", type => 'submit', value => 'Search', ]; my $res = $ua->request($req); unless ($res->is_success) ## or perhaps: if ( !$res->is_success ) { $n_attempt++; print STDERR "$someParam ERROR: Try# $n_attempt" . $res->status_ +line . "\n"; sleep(1); redo RETRY if $n_attempt <= MAX_RETRY; print "$someParam,ERROR: Try# $n_attempt" . $res->status_ +line . "\n"; next; #Maybe you something different here???? } $raw_html = $res->as_string; #...do some normal processing... #then loops to next value of $someParam... }
First set your loop up for the "good machine case" and get that working. Then think about the 1/1000 case that doesn't work. If the loop is gonna fail say 1/10th the time, then I would put the fail conditions in the loop iteration decision making. But if we are talking about a rare occurrence, I would put the processing of that in the "gut's"..not in the major loop condition! In your case ftp is gonna work! Well almost all of the time, given that you are authenticated, etc. But it can fail like 1/5000 times.

Perl has a cool thing called "redo". Read about it in the manual, but basically this causes the loop to go again without evaluating the, in this case while() statement again. Here I used a labeled redo, called RETRY although here this RETRY label is not strictly necessary. I just thought it "looked better" and was easier to understand.

Of course "next" operates just like what you would think..it loops back to and evaluates the loop condition again ("hey, I'm done with this one, I want a another one").

Anyway when considering things to do other than "give up" and die, think about what you would do...is a retry likely to succeed? If something really "blows up" are you willing to deal with the aftermath? If some guy comes along and cuts my internet cable, this program will spew 30-100K lines of BS into a log file. I thought about that and I'm ok with it.

In general your options are limited when "it didn't work". (a) try again, (b)skip this request and go the next request, (c) completely give up (die).

I hope I've helped you with some ideas.

  • Comment on Re: How do I use a block as an ‘or’ clause instead of a simple die?
  • Download Code

Replies are listed 'Best First'.
Re^2: How do I use a block as an ‘or’ clause instead of a simple die?
by ikegami (Patriarch) on Apr 18, 2009 at 18:47 UTC

    Problem #1: You have an "or" statement, not a subroutine block therefore a return(-1) is nonsense...return -1 to where and to whom?

    No, there's no reason to believe there's a problem with return. The snippet comes from a sub, that's all.

    What I find odd is returning a true value on error. But it's not unheard of in specific circumstances (e.g. getc, index).

      I had to hit CTL-+ a couple of times to get fonts large enough that I could see the details. I see your point, but even so, this -1 return value is very strange...there can be complications with signed vs unsigned, etc.

      Returning a non-zero value for an error is actually the "normal" way to do things. If I can only transmit one single number to you and that number has to combine the error code and the success status into that single number, then "success" has to mean Zero. Zero means I am completely happy. Something non-Zero is an error code. What's weird here is the -1.

      This all has to do with ancient stuff. A lot of these machines only had two registers, A and B, each 16 bits. In ASM, by convention simple status would get passed back to caller via A register. PDP-11, SEL-810, NOVA-800,etc. Now if all the bits were "on" FFFF, then is that -1 or 65535?

      Even the most wimpy machines will have a JNZ (jump non zero) or JZ (jump zero) instruction - it can be called something else, but there will be something like that. To detect -1 would have taken 2 instructions: one's complement(XOR), then JNZ or JZ. On a modern processor, the math unit is FAR larger than the CPU. All this happens at mind boggling rates.

      Anyway, yes there is a false dichotomy concerning "true/false" values. All I can say is that it is what it is.

        In Perl, false values are customarily used for errors (and not just for builtins).