SUMMARY A proposal for a set of loop structures that simplify code that is based on loop iterations.
foreach my $var (@arr) { ... } before { ... } # run before first iteration, only if there is at least one iteration between { ... } # run between iterations, not before first or after last after { ... } # run after last iteration, only if there is at least one iteration noloop { ... } # run if there are no iterations DETAILS Virtually every time I write code for a loop I need to do some set of stuff before the loop (if there were actually any loops), some more stuff after the loop (again, only if there were actually any loops), and yet another bunch of stuff if there were no loops at all. I also frequently need to do something only between loops, but not before or after. For example, suppose the code loops though the results of a search. The code should output a header at the top, a footer at the bottom, an <HR> between each loop, and should do none of that if nothing was found. (This example is only slightly exagarated: except for the <HR> in between, all my searches do all of that.) Currently we would implement these requirements using an iteration counter: my $counter = 0; foreach my $res ($myob->getresults) { if ($counter) { # output divider } else { # output header } # do stuff to display the result $counter++; } # close if there were any loops if ($counter) { # output footer } # lack of results message if no loops else { # print "no results" message } Now, I'll be the first to admit that that isn't a terribly complicated algorithm, but it took me while to come up with that algorithm and it always feels like I have to contort my code to make it work... the header goes inside the loop when I feel like it should go before the loop, the divider comes before the header (or I have to use "if not", which means doing a confusing test for a negative). The proposed solution is similar to the benefit foreach gave us: it just makes things easier. It organizes the code into logical blocks based on the process of looping through the elements: before { # output header } foreach my $res ($myob->getresults) { # do stuff to display the result } between { # output divider } # footer if there were any loops after { # output footer } # lack of results message if no loops noloop { # print "no results" message } The blocks should go outside the loop, not inside like has been discussed for other loop controls. None of these structures are about the process inside any particular iteration... they are always outside of any specific iteration. Also, it would make sense to allow "before" to go before the loop... after all, it's stuff that happens before the loop. -Miko