Hello

The impetus:

I agree, except I more and more think that scope classes were a mistake. 
Structs with destructors are a much better solution, and wrapping a class 
inside a struct would give it RAII semantics.

The problem:

In designing a library (or rather touching up someone else's library), I have a class (interface?) Foo, and it has a method close (actually several methods). Almost invariably (although conceivably not always), usage involves manipulating Foo, and then remembering to call close. That last part is obnoxious.

One obtains a Foo from function foo.

What I'd like is for the result of foo to have RAII semantics by default, with the possibility of nixing it if the user actually cares.

I want to take the burden of remembering that stupid close off the user.

For example:

void bar(){
  auto a = foo();
  a.doStuff();
}

has an implicit call to close after doStuff.

The impetus suggests I can do this by wrapping Foo inside a struct, but I'm not so sure how well this would work out. Also note that close can fail in a number of ways relating to file io.

So I wrote up a simple prototype.

Thoughts?




import std.stdio;
class Foo{
    int k;
    this(int i){
        writefln("bin %d",k);
        k = i;
    }
    void doStuff(){
        writefln("do stuff %d",k);
    }
    void close(){
        writefln("close %d",k);
    }
}
struct RAII(T){
    T b;
    bool extracted = false;
    alias b this;
    this (T i){
        assert(i !is null);
        writeln("in");
        b = i;
    }
    ~this(){
        writeln("~this");
        if(!extracted) b.close();
    }
    T extract(){
        assert(!extracted);
        T t = b;
        b = null;
        extracted = true;
        return t;
    }
}
RAII!(Foo) foo(int i){
    return RAII!(Foo)(new Foo(i));
}
void main(){
    auto a = foo(1);
    auto b = foo(2).extract();
    a.doStuff();
    b.doStuff();
}


Reply via email to