[Tutor] Re: Request for code critique ['break' vs control flag]

Alan Gauld alan.gauld at blueyonder.co.uk
Sat Oct 25 19:45:33 EDT 2003


> > on actual hard data. Having multiple exit points makes code
> > harder to comprehend and hence more prone to error.
>
> Aren't exceptions a kind of exit?

Yes, but by definition not part of the normal program flow.
The try/except mechanism is a way to remove multiple exits
from a block.

try
   [ code block with 'happy path']
except
   [ all the exceptions that would have broken up the block]

So in terms of legibility the core code block is made easier
to read because the exception handling has been moved outside.

The alternative is:

[ some code here]
if <exception>
   [handle it]
   [exit block]
[more happy path code]
if <another exception>
   [handle it]
   [exit block]
[more happy path]


I think most folks find the try/except style easier to comprehend,
precisely because it doesn't break up the main block of code.

One of the valid reasons for using break/continue (and the original
reason for them being in C) is to do exception processing within
loops, the only alternatives are maintaining multiple error flags
or using GOTO... In that case break is better. But it is, quite
literally, the exception and not the rule.

> Personally, I think multiple exits are great.  At work I'm
responsible
> for maintaining some extremely ugly Java code (it looks more like C
> than Java, taking little advantage of OO), and one of the things I
am
> doing is applying refactorings it to make it more readable.

> find it much more readable to use use "Extract Method" refactoring
to
> put some large chunk of code into a purposefully-named utility
method
> (read: "function"), and return values explicitly from the point in
the
> code where the processing can stop -- otherwise the reader has to
> continue to read the code long past the point where the flag is
finally
> set, and make sure that it's not being re-set at some point later in
> the code, before it's finally returned.

Refactoring is generally a good thing and has been recommended
long before it was called refactoring...

However even here some intelligence must be applied. For example
if a function is written to handle a long and complex data structure
it is tempting to break it into chunks, each chunk handling a
section of the structure. Often this works. But if the manipulation
of one part relies on values set in an earlier part then the values
have to be passed into the sub functions creating a dangerous
degree of coupling that may cause problems in the future.

For example, one of the biggest functions I ever saw was
about 300 lines long, but it made no sense to break it up
(refactorig it) because it was processing a data structure which
itself was over 100 lines long(this was in C). And because
there was no real repetition within the structure and there were
many internal dependencies in the values. To refactor it
would have led to a maintenance nightmare.

The usual rule applies: the structure of the data should determine
the structure of the code!

As I said in an earlier post, we live in an imperfect world
and purity must often be sacrificed for prgmatism. But the
compromises chosen should be based on a clear understanding
of the impacts, both positive and negative.

Alan G.




More information about the Tutor mailing list