try..catch..pass..finally Was: DMD 0.148 - scope guard
Regan Heath
regan at netwin.co.nz
Sat Mar 4 02:08:13 PST 2006
On Sat, 4 Mar 2006 01:09:47 -0800, S. Chancellor
<dnewsgr at mephit.kicks-ass.org> wrote:
> On 2006-03-01 02:15:35 -0800, "Walter Bright"
> <newshound at digitalmars.com> said:
>
>> "S. Chancellor" <dnewsgr at mephit.kicks-ass.org> wrote in message
>> news:du376e$1fbf$2 at digitaldaemon.com...
>>> 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);
>>> }
>> Should be:
>> f = dofoo();
>> scoped.failures ~= void delegate () { dofoo_unwind(f); }
>> etc. Other than that, it looks like it'll work, but it's a lot more
>> code than on_scope. You also need to be sure that the delegates don't
>> refer to any variables declared inside the try block, as those
>> variables no longer exist in the catch block - and the compiler can't
>> catch that error. This isn't a problem with on_scope.
>
> Why would that be the case? If dofoo() throws an error, that delegate
> would not yet be appended to the failures delegate array. Thus it
> wouldn't be able to do it's job in the catch block. I know your and
> derek's order was like this originally, but it seemed like a typo so I
> fixed it.
The idea of dofoo_unwind is to reverse the changes made by dofoo when
dofoo succeeds and a later step fails. If/when dofoo throws it should undo
it's own changes before returning.
Regan
More information about the Digitalmars-d
mailing list