scope guards

Manu via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 4 03:01:32 PDT 2014


On 4 August 2014 17:13, Jacob Carlborg via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:

> 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.


Yes, but there's no try block, and it is sequenced properly along with any
other scheduled scope events.


 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
> }
>

catch can't appear on its own though... or are you suggesting that it
should be possible?


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.
>

I was actually going to suggest that, except I deleted that part of my
email thinking I was already getting too elaborate ;)

void foo ()
> {
>     connectToDatabase();
>
>     catch (DatabaseException e)
>         cleanup();
> }
>

Yeah, that. Except I think scope(failure, Exception e) also has a place;
there are instances where you don't want to stop the unwind, but you do
want to be able to retrieve some information from the exception during the
unwind... useful for error recording or context sensitive recovery.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20140804/bac22410/attachment-0001.html>


More information about the Digitalmars-d mailing list