TrackBack URL for this entry: http://www.unix-girl.com/mt/mt-tb.cgi/1197
Even when they simplify reading the code?
#They never simplify debugging code.. and it's a rare case when using multiple return statements in Java simplifies reading code.. That may just be my experience though.
#I'll toss my vote in with Jeremy's. I often find multiple return statements can reduce covoluted ramblings to propogate a return value to the end of a loop, and/or avoid deeply nesting conditionals.
But maybe that's just me.
#End the loop? Break?
#I don't recall having had problems debugging code because of multiple returns, and I think code tends to be somewhat less readable when you try to use one return statement [lots of protective if(EVERYTHINGS_FINE) ...].
To get out of loops, labeled continue/break helps somewhat, but I'm still not really comfortable with them.
#I'll agree with Jeremy, too.
You can really clean up a method with a well-placed return statement or two. I find it a lot easier to read methods that return as soon as they have reason to, instead of hanging on because they need to reach some single exit-point.
The only disadvantage I see for debugging is that it's slightly harder to log a method's return value inside the method. Kasia: Maybe an example of what specifically annoyed you?
#Everything used in the smart way its ok, surely there is not difficult to find neat multiple returns and very ugly ones.
BTW I hate even more the evil habit of returning Object in methods that only can return 1 or 2 different object types forcing to cast everywhere to get the same kind of object again and again. Maybe its just me, but it was a nightmare when I was profiling the code of my coworkers.
#Reminds me of the good ole' days when discussions about coding standards the topic of the day.
Multiple return statements are "neccesary evil", better if they can be avoided, and should not be a practice.
#It's not multiple return statements that are the problem: it's convoluted logic.
If you have simple, clean methods, then having three or four different exit points aren't a big deal: especially when most of them are "early-exits" dealing with error handling.
IMHO, 99% of the time that multiple return statements complicate debugging, it's the convoluted logic around the returns that cause problems. Having code that needs to set external "retValue" variables, and break out of (possibly nested) loops is often even harder to read or debug.
#Anyone who has ever relied on weblogic for testing code should know how hard it is to keep it from core dumping when running in a debugger (seriously, it's a huge problem) and unit tests aren't always practical since the test environment cannot be accurately duplicated (otherwise, you just wrote an EJB server, congrats)... Hence debugging with print statements, while primitive, is very useful.. Now do that effectively when you have multiple return statements.
Well structured code can be readable w/o the use of multiple return statements.. there are ways to avoid nested loops and chains of if/elses. So okay, maybe this is a personal issue, but it's a grating one for me.. everytime I run into this it's convoluted logic and the code is *not* easier to read but harder.
Guys, I'm talking about Java, an object oriented language.. if your code becomes easier to read by creating multiple return points, perhaps it's time to look into restructuring it into methods/object? There's this old adage.. if a method doesn't fit on the screen it's too big.
#Luis, that's not bad, that's evil..
#Sorry - I'm fine with multi-returns as well both for me and from students. Especially when dealing with a lengthy run of network related code.
Think of it this way... if I used an if to go into each section of code that passes, rather than using the return to hop out of the loop, and I've got 12 if's to go through, I'll be so indented in the code that I won't be able to read it without horizontally scrolling... instead I code the if's by exception: if the 3rd part of the chain fails, get out of the proc and ignore the other 9... just feels cleaner.
#Look at it this way.. you're running production code, something goes awry.. so you turn on debug and examine everything.. with multiple returns, you suddenly either (a) never reach the end of the method were all relevant data is dumped out (return value, for instance) or (b) need to put out debug output at each return.. suddenly simplification is no longer a reason.
in case of chained calls like that, Randy.. why not use a case statement?
'kay, so there are as many ways of coding as there are programmers, if you're fiddling with my code though, don't do that, how's that :)
#Kasia, how are you debugging the weblogic operation?
I tried to debug it remotely (using the JPDA) and it crashed badly sometimes.
What I did is to run it as an application inside my IDE debugger. That way I'm able to put breakpoints at sevlet, POJOs and EJB and it works like magic.
The only caveat is that you can't "step into" a method in an EJB (it crashed my debugger also). Instead you must put a beakpoint in the implementation on the method you need to debug.
#Rafael, I use a socket connection to the JVM, for various reasons, that's my only choice, and yah, you can't really set breakpoints at methods, need to do it at lines of code.. (did I mention I hate weblogic? JBoss has *none* of these issues and it works at a decent speed in a debugger).
I see I'll have to do an entry tonight on named code blocks in Java :)
#PMD can check for this:
http://pmd.sourceforge.net/rules/controversial.html
Note the ruleset name, though - "controversial". It's in there alongside AssignmentInOperandRule and AtLeastOneConstructor.
#I agree with Roger and Jeremy: multiple returns can definitely make code more readable.
What I've seen in some peoples code that makes debugging hard is huge multi-line conditions or expressions. For debugging purposes, it's beneficial to break the condition or expression in smaller chunks and create a tempory variable for each chunk. That way I can easily dump out the various chunks in a debugger or via a System.out.println() to find out why things are going awry.
#It seems unusual to me to write code in a certain way because of debugger limitations.
I personally find multiple return statement algorithms to simply be another tool in a developer's toolset, nothing more, nothing less.
I become very leery of any rule in software development that begins with 'Never...' or 'Always...'.
#In a short method, I find multiple returns OK, but I can understand that they would make it difficult to log or print the method's return value.
I've only ever seen "break" used in the middle of code that is far too complicated, and should be refactored into separate methods anyway.
As for "continue", that only seems to be used in multi-page for loops.
I suppose it's what you're used to.
Kasia says: "in case of chained calls like that, Randy.. why not use a case statement?"
He's not talking about chained ifs testing similar conditions -- he's talking about *nested* ifs, each testing for success of the previous section of code. Basically, each if is a checkpoint.
That's something completely different from what case is for.
For checkpoints (or guard statements, or however you might prefer to call them), it is indeed much clearer to return on failure rather than nest down another level on success.
#yes, you're right.. i misunderstood, but fear not, not only do I understand what case statements do -- I even have an answer to Randy's dillemma in the next entry..
#I disagree.
#There is no excuse for multiple return statements - you can just use a single return statement and put GOTOs in the code where needed.
#If you're just debugging with multiple returns statements and can't be bothered with adding multiple debug statements to get the return value (copy and paste anyone?), you could always wrap all the function's code in a try..finally and do the debug in the finally.
Remove the try..finally after your debugging though to avoid the performance hit.
#