in reply to A matter of style
I'll never return from the "middle" of a routine as i find it makes debugging a little more difficult as there are multiple "areas" where the routine can be exited from. Beside the semantic validation at the top of the routine the exit will always be at the bottom before the } Purists say there should only be one entry and one exit and anything else is obfu. What do you say?
I think it depends on the application and on the routine. There are cases where having multiple return points makes for clearer, more readable code than the alternatives available. I don't have a good example in Perl off the top of my head, but here's one in another language... the following is a parse_name routine I wrote for a class of objects (matches, as it happens). (The language is Inform, and is mostly self-explanatory if you are familiar with computer languages in general. You do need to know that the switch statement implicitely breaks after each case, unlike C.)
What makes multiple exit points really necessary is that we're parsing a stream of words, and at any point when one does not match, we have to stop; yet, the same word may match or not match depending on a variety of conditions that depend on the state of the object. Here is the code...
! What self.number means: ! 0 Never used ! 1 Attempted to strike once ! 2 Attempted to strike twice ! 3 Attempted to strike thrice ! 4 Phosphor gone from failed striking. ! 5 Just lit. ! 6-9 Burning down progressively. ! 10 Burnt out. ! 11 Burnt out, but prematurely. parse_name [ w n; if (parser_action==##TheSame) { ! The actual code had some more stuff here, to handle ! the case where the parser is asking us whether two ! objects of the class are distinguishable, but I've ! snipped that out for brevity. } ! Otherwise we're just determining how ! many words refer to it: for (::) { w = NextWord(); switch(w) { 'match': n++; 'matches': parser_action = ##PluralFound; n++; 'burning', 'lit', 'light', 'lighted', 'alight', 'brightly': if (self.number<5) return n; if (self.number>9) return n; n++; 'glowing', 'dim', 'dimly': if (self.number~=5) return n; n++; 'burnt-out', 'burnt', 'burned', 'burned-out', 'charred': if (self.number<10) return n; n++; 'worn', 'worn-out': if (self.number~=4) return n; n++; 'out': if (self.number~= 4 or 10 or 11) return n; n++; default: return n; } } ],
I cannot imagine the obfuscation that would result from trying to make that routine (or a longer one like it) exit in only one place. A couple of additional variables would be needed, plus additional conditionals, and the for loop would become needlessly complex, and it would just be a big mess -- especially for a longer routine. (I chose a relatively short parse_name routine for simplicity of example; they can be much longer if, for example, certain words only match if certain other words are also used, in certain sequences, and so on and so forth. If you have an eighty-line parse_name routine, you do NOT want it exiting in just one place.)
Now, it can certainly be argued that this parsing problem is atypical; it is certainly atypical of the kinds of things we usually use Perl for. So there may well be lots and lots of cases where a single exit point is desirable. All I'm saying is, there are also cases where that's not so.
sub A{while($_[0]){$d=hex chop$_[0];foreach(1..4){$_[1].=($d %2)?1:0;$d>>=1;}}return$_[1];}sub J{$_=shift;while($_){$c=0; while(s/^0//){$c++;}s/^1//;$_[1].=(' ','|','_',"\n",'\\','/' )[$c]}@_}$PH="16f6da116f6db14b4b0906c4f324";print J(A($PH));
|
|---|