DIP44: scope(class) and scope(struct)

Dmitry Olshansky dmitry.olsh at gmail.com
Sat Aug 24 10:31:52 PDT 2013


24-Aug-2013 04:44, H. S. Teoh пишет:
> I've written up a proposal to solve the partially-constructed object
> problem[*] in D in a very nice way by extending scope guards:
>
> 	http://wiki.dlang.org/DIP44

>
> Destroy! ;-)
>

Instead of introducing extra mess into an already tricky ctor/dtor 
situation. (Just peek at past issues with dtors not being called, being 
called at wrong time, etc.)

I'd say just go RAII in bits and pieces. Unlike scope, there it works 
just fine as it has the right kind of lifetime from the get go. In 
function scope (where scope(exit/success/failure) shines) RAII actually 
sucks as it may prolong the object lifetime I you are not careful to 
tightly wrap it into { }.

Start with this:

class C {
     Resource1 res1;
     Resource2 res2;
     Resource3 res3;

     this() {
         res1 = acquireResource!1();
         res2 = acquireResource!2();
         res3 = acquireResource!3();
     }

     ~this() {
         res3.release();
         res2.release();
         res1.release();
     }
}

Write a helper once:

struct Handler(alias acquire, alias release)
{
	alias Resource = typeof(acquire());
	Resource resource;
	this(int dummy) //OMG when 0-argument ctor becomes usable?
	{
		resource = acquire();
	}

	static auto acquire()
	{
		return Handler(0); //ditto
	}

	~this()
	{
		release(resource);
	}
	alias this resource;
}


Then:

class C{
     Handler!(acquireResource!1, (r){ r.release(); }) res1;
     Handler!(acquireResource!2, (r){ r.release(); }) res2;
     Handler!(acquireResource!3, (r){ r.release(); }) res3;
     this(){
	res1 = typeof(res1).acquire();
	res2 = typeof(res2).acquire();
	res3 = typeof(res3).acquire();
     }
}

There are many more alternatives on how to auto-generate RAII helpers. 
The point is we can easily do so, after all our compile-time kung-fu is 
strong.

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list