try..catch..pass..finally Was: DMD 0.148 - scope guard
S. Chancellor
dnewsgr at mephit.kicks-ass.org
Tue Feb 28 20:16:29 PST 2006
On 2006-02-27 23:17:06 -0800, "Regan Heath" <regan at netwin.co.nz> said:
> On Tue, 28 Feb 2006 06:34:00 +0000 (UTC), Tom Johnson
> <Tom_member at pathlink.com> wrote:
>>> I'd say add another option to try..catch..finally paradigm.
>>>
>>> -S.
>>
>> Seconded. For more fun, next we can debate whether the syntax should be:
>>
>> 1. try..pass..catch..finally
>> 2. try..catch..pass...finally
>> 3. try..catch..finally..pass
>
> No, on_scope gives us more than try/catch/finally. Let me try this
> another way.
>
> "catch" from try/catch/finally allows:
> - you to execute a static/pre-defined set of code in the event that
> there is a failure in the current scope.
>
> "finally" from try/catch/finally allows:
> - you to execute a static/pre-defined set of code at the exit of the
> current scope in all cases.
>
> Compare that to:
>
> on_scope_failure allows:
> - you to add one or more sets of code, at the points at which they
> become required, to the list of things to execute in the event of a
> failure.
>
> on_scope_exit allows:
> - you to add one or more sets of code, at the points at which they
> become required, to the list of things to execute at the exit of the
> scope in all cases.
>
> To achieve the same thing that on_scope gives with try/finally requires
> you to store state somewhere to indicate which parts of the finally
> block to execute, or, it requires that you define several finally
> blocks and nest them. Both of those options are no where near as neat
> as on_scope.
>
> I'm honestly baffled that people can't see the difference.
>
> Regan
Ah. I see what you want. I was a bit confused about this before.
This is just syntatic sugar to a relatively easy to write class though.
Maybe it should be part of the standard library?
It essentially acts like a multi-homed delegate which is implicitly
called at the end of the scope.
Something like this would be equivalent?
Transaction abc()
{
Foo f;
Bar b;
Def d;
Auto scoped = new Scoper(); //scoped.exit() can be called by the
destructor. We won't add a finally block.
try {
scoped.failures ~= void delegate () { dofoo_unwind(f); }
f = dofoo();
scoped.failures ~= void delegate () { dobar_unwind(b); }
b = dobar();
scoped.success()
} catch (Exception o) {
scoped.failed()
throw o;
}
return Transaction(f, b, d);
}
It seems to me Walter's class example doesn't exactly do this justice.
I find this fully acceptable for the few places I would use this. The
implicit instantiation of an object like this might be nice though, if
it only added the extra code when it was referenced. Which should be
trivial to do. I'd much rather have an "implicit" scope object than
this, or the current syntax.
-S.
More information about the Digitalmars-d
mailing list