scope guards

Jacob Carlborg via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 4 00:13:18 PDT 2014


On Sunday, 3 August 2014 at 15:28:43 UTC, Manu via Digitalmars-d 
wrote:
> I'm trying to make better use of scope guards, but I find 
> myself belting
> out try/catch statements almost everywhere.
> I'm rather disappointed, because scope guards are advertised to 
> offer the
> promise of eliminating try/catch junk throughout your code, and 
> I'm just
> not finding that to be the practical reality.
>
> I think the core of the problem is that scope(failure) is 
> indiscriminate,
> but I want to filter it for particular exceptions. The other 
> issue is that
> you still need a catch() if you don't actually want the program 
> to
> terminate, which implies a try... :/
>
> One thing that may be leveraged to eliminate most catch blocks 
> is the
> existing ability to return from scope guard blocks, allowing to 
> gracefully
> return from a function while unwinding, akin to a catch.
> The problem then is that you can't handle specific exceptions.
>
> I'm thinking this would make all the difference:
>
> scope(failure, MyException e) // only executed for exceptions 
> of type
> MyException
> {
>   writeln(e.msg); // can refer to the exception in this failure 
> block
>   return failureValue; // and can gracefully return from the 
> function too
> }
>
> That would eliminate about 80% of my try/catch blocks.

That is exactly like a catch-block.

> The remaining suffer from the problem where I want to respond 
> to exceptions
> NOT of a specific type, ie, clean up in the case of an 
> unexpected/unknown
> exception.
>
> scope(failure, ~MyException)
> {
>   // clean up, because some unexpected exception occurred that I
> don't/can't handle.
> }

That I can agree would be useful, but within a catch-block 
instead. You can always manually check the type of the exception.

catch (Exception e)
{
     if (auto myException = cast(MyException) e)
         // handle
     else
         // cleanup
}

Of course this logic could be nicely handled with AST macros ;)

> Is there already some mechanism to do this? I couldn't find 
> anything in the
> docs.
> It seems like an obvious thing to want to do.

It seems like you want to have a catch-block without a try-block. 
I think that would be useful. A catch-block without a try-block 
would implicitly add a try-block to the same scope as the 
catch-block or to the closest function body. Ruby has this and 
it's quite nice.

void foo ()
{
     connectToDatabase();

     catch (DatabaseException e)
         cleanup();
}


More information about the Digitalmars-d mailing list