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

Reply via email to