Section 6.21. Redoing


6.21. Redoing

Use for and redo instead of an irregularly counted while.

In the final version of the input code shown in the previous guideline, a while loop plus a count variable ($TRies) was replaced by a for loop. This is a good practice in any situation where a while loop is controlled by a variable that is linearly incremented on each iteration. Using a for makes explicit your intention to loop a fixed number of times. It also eliminates both the count variable and the need to explicitly test that variable against some maximal value. That, in turn, removes the possibility of forgetting to increment the variable and the risk of off-by-one errors in the explicit test.

However, this kind of loop refactoring is satisfactory only when the count variable is uniformly incremented on every iteration. There are plenty of situations where that is not quite the case; where the count is usually incremented each time, but not always. Such exceptions obviously create a serious problem in a fixed-repetition for loop.

For example, the previous example didn't count an empty input line as a legitimate "try". That was easy to accommodate in the "while ($tries < $MAX_TRIES)" version; you simply don't increment $tries in that case. But, in a for loop, the expected number of iterations is fixed before the loop even starts, and you have no control over the incrementing of the loop variable. So it would seem that a for loop is contraindicated whenever the iteration-counting is irregular.

Fortunately, the redo statement allows a loop to have its cake (i.e., be a for loop instead of a while) and eat it too (by still discounting certain iterations). That's because a redo sends the execution back to the start of the current iteration of the loop block: "Do not pass for. Do not collect another iterated value."

Using a redo allows you to take advantage of the fixed-iteration semantics of a for loop (with their cleaner and more maintainable syntax), but still allows controlled deviations from a fixed number of iterations when necessary. It also makes the program's control flow more obvious and comprehensible. There is no longer any need to decode the implicit behaviour caused by (non-)changes to the value of a count variable. Instead, every exception to the fixed number of repetitions promised by the for loop is explicitly marked with a redo keyword.

For these reasons it's a good practice to replace any "counted" while loop with a for loop, and then to use a redo in any situation where the count should not be incremented for that particular iteration.

Unfortunately, this practice does not generalize to situations where the count must be decremented in any way or increased by more than one. In such cases, a while-plus-$count is the correct solution.



Perl Best Practices
Perl Best Practices
ISBN: 0596001738
EAN: 2147483647
Year: 2004
Pages: 350
Authors: Damian Conway

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net