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