On page 548 of Blue Camel, it is written:
Perl provides the last operator so you can exit [a loop] in the middle. Just "outdent" it to make it more visible:Note how last is outdented but next is not; why one loop control statement and not the other? And what would be done if the last were not conditionalled by an if modifier but contained within an if block? Outdent the if, even though the block probably contains other statements than the last, probably unrelated to loop control? Outdent the last all the way past the left margin of the for's block, therefore beyond the left margin of the if?LINE: for (;;) { statements; last LINE if $foo; next LINE if /^#/; statements; }
Both of those options are terrible, and even though the outdent sort of works in the simple case given above, it could easily be misconstrued by someone unfamiliar with the convention as merely sloppy prettyprinting to be corrected, rather than as a "feature". This probable misinterpretation makes the convention less likely to be used, and the resulting obscurity makes it even less likely to be recognized.
Here's how I would prettyprint that block:
for (;;) { statements; ; last if $foo; ; next if /^#/; statements; }The leading semicolons always line up with the top keyword of the control structure to which they apply, but the control statements themselves are indented consistently with their position in possibly-nested control structures. Note that
for (;;) { statements; if $foo { statements; ; last; } ; next if /^#/; statements; }works just fine.
Using this convention in C++, I actually once had it detect a bug. A for was wrapped around an if...else if structure, with breaks inside the conditional. I later converted the conditional to a switch, so the breaks had become bogus. But the semicolons were still lined up with the control structure that the breaks had been intended to refer to, so as soon as I reread the code (before it was ever compiled) I spotted the error and converted the breaks to gotos.
In practice I find this coding technique robust enough that I don't need to use labels like LINE in the Blue Camel version on my fors. In the event that they are still desired, I'd suggest replacing
LINE: for (;;) { statements; last LINE if $foo; next LINE if /^#/; statements; }with
LINE: for (;;) { statements; ; last LINE if $foo; ; next LINE if /^#/; statements; }to conform to what in Chapter 18 of Code Complete Steve McConnell calls the "Fundamental Theorem of Formatting": good visual layout shows the logical structure of the code. Indenting the for under the LINE implies that for is logically subordinate to LINE, but it's not; it's at the same logical level. LINE is the leading token of the control structure. Recognizing that "LABEL: keyword" is the top of a control structure is relatively easy compared to recognizing that "LABEL:\n{indent}keyword" is all the top of a control structure. Also, it's less important that the leading token of the structure be a keyword like for, since the semicolons always show what the nested control statements were intended to apply to. The form in Blue Camel takes an extra line of code and an extra level of indentation, neither of which help show the logical structure of the code.