in reply to A matter of style

Purists say there should only be one entry and one exit and anything else is obfu. What do you say?

One entry to a subroutine yes. One exit no. Many people have disagreed with this point and for good reason. It increase code clutter, it increases code complexity, and often increases code duplication. About the only really useful argument that I can think of for only having one exit to a routine is to be able to positively determine the returned value. But theres lots of ways around that without losing clarity.

sub one_exit { my $foo=shift; my $return=shift; CORE:{ last CORE unless $foo; #... last CORE if $foo eq "bar"; #... } return $return }

or even easier is to just rename the sub for a bit and create a wrapper that calls it, allowing you to intercept its entry and exit, without artificial constraints confusing your code.

---
demerphq


Replies are listed 'Best First'.
Re: Re: A matter of style
by pfaut (Priest) on Feb 14, 2003 at 23:11 UTC

    When using procedural languages, I usually try to maintain a single exit from a procedure. I have had several occassions where I had to add some cleanup code at the end of a procedure. Since the procedure had multiple exits, I had to do some searching to find all of them and then rework the code so it would all fall off the end. On the other hand, I'm not a purist -- if the code starts getting too twisted in order to pull this off, I'll use additional returns or (gasp!) a goto.

    Lately, though, I've been working more with object oriented languages than with procedural languages where this has been less of a concern. Most of the things that would need cleaning up get handled automatically by destructors of objects going out of scope. In case of errors, I'm probably using a throw instead of a return, though.

    In perl, a common exit can easily be implemented with a naked block inside the routine. Use last instead of return inside the block and have all cleanup code following the block. I've seen similar things done in C with a do { ... } while 0;.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
      If you have a procedurial language and you have multiple exit points from a procedure, and then you want to do some "exit" actions, you could do the same trick as you would with an OO language. You mask the procedure by another one, that calls your original procedure, and then does the exit actions. Except that with an OO language, you typically create a new class that calls a procedure with the same name in the original class, but with a procedural language, you rename the original procedure, and create a new procedure with the original name, that calls the original procedure, and then does the exit actions. Same technique, different syntactical details.

      Abigail

      In perl, a common exit can easily be implemented with a naked block inside the routine.

      I provided an example of this in my node. :-) I also mentioned the approach that Abigail-II suggests.

      ---
      demerphq