Did we forget why "multiple exit points" was considered harmful in the first place? Back in the day (before widespread access to good exception handling and finally constructs, or managing objects like auto_ptr
that do cleanup when they leave scope), this was the problem that haunted many multi-exit functions:
int function blah(arg1, arg2)
allocate resource
if early failure detection
return failure_status
... much later...
release resource // oh rats! resource didn't release
return success_status
If the resource is memory, this creates a memory leak. If it's a database transaction, we are heading for bad database contention or deadlock. For that matter, with the advent of more exception support, we implicitly add many potential exits from a method (by virtue of an unhandled exception). In my C++ days, I developed the habit of never calling delete, but instead using auto_ptr
, so that allocated memory was cleaned up when the auto_ptr
exited its scope, even if some unexpected exception reared its head.
In our garbage collected Python world, we can still have this issue, even though many of our objects, such as files, or locks, have improved self-cleaning behavior. But in implementations other than CPython (jython and IronPython to name two), there is no guarantee just when a destructor will get called, so something more proactive needs to be built into your method. The first mechanism for this purpose was try/finally:
int function blah(arg1, arg2)
allocate resource
try:
if early failure detection
return failure_status
... much later...
return success_status
finally:
release resource // always releases no matter what
But now Python has context managers, in conjunction with the new 'with' syntax:
int function blah(arg1, arg2)
allocate resource
with context_manager(resource): // releases on exit from 'with'
if early failure detection
return failure_status
... much later...
return success_status
So let's be sure that we tell the whole story, that the reason we can discard this old chestnut is that newer coding practices make it unnecessary.