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