digitalmars.D - extension to scope
- Alex Burton (35/35) Jan 28 2007 I would like to say that the ability to declare a class reference as sco...
- Frits van Bommel (26/69) Jan 28 2007 The "if no other references exist" part can be a bit hard to determine
- Max Samukha (3/8) Jan 29 2007 It seems like this feature would beat the .NET Framework's
I would like to say that the ability to declare a class reference as scope, which guarantees that the destructor is called when exceptions occur, is a great feature that allows much more elegant code than putting try catches every where. However I think that it is somewhat limited in that references to other objects held by the class are not guaranteed to be freed. I would like to see the scope keyword's meaning extended so that any objects referenced by the scoped class are freed if no other references to them exist, and that this is done recursively. This would allow the logical use of scope beyond simple little convienience classes to large transaction type objects which need to be rolled back when an exception occurs. This is of great importance to me when I have classes representing a transaction that may use some real resources such as files, ports etc. Using an example I would like the code below to output ~C ~B ~A finished import std.stdio; class A { ~this() { writefln("~A"); } }; class B { A a; this() { a = new A(); } ~this() { writefln("~B"); } }; class C { B b; this() { b = new B(); } ~this() { writefln("~C"); } }; int main() { { scope auto x = new C; } writefln("finished"); return 0; }
Jan 28 2007
Alex Burton wrote:I would like to say that the ability to declare a class reference as scope, which guarantees that the destructor is called when exceptions occur, is a great feature that allows much more elegant code than putting try catches every where. However I think that it is somewhat limited in that references to other objects held by the class are not guaranteed to be freed. I would like to see the scope keyword's meaning extended so that any objects referenced by the scoped class are freed if no other references to them exist, and that this is done recursively.The "if no other references exist" part can be a bit hard to determine without running a full GC cycle or some tricky analysis by the compiler.This would allow the logical use of scope beyond simple little convienience classes to large transaction type objects which need to be rolled back when an exception occurs. This is of great importance to me when I have classes representing a transaction that may use some real resources such as files, ports etc.If you ensure that no other references exist, you can just tell the members to clean up after themselves and then delete them. See the modifications I made to your code:Using an example I would like the code below to output ~C ~B ~A finished import std.stdio; class A { ~this() { writefln("~A"); } }; class B { A a;replace with: private A a; // to make sure no other references exist /// Call this to clean up before deleting instances of /// this class, to clean up resources. void close() { delete a; }this() { a = new A(); } ~this() { writefln("~B"); } }; class Creplace that line with: scope class C // to make sure it never gets deleted by the GC{ B b;private B b; // to make sure no other references existthis() { b = new B(); } ~this() { writefln("~C"); }Because of the 'scope' at the start of the class declaration, it is now safe to reference member objects in the destructor. (That's undefined behavior when it's called by the GC, but scoped classes don't get deleted by the GC) So replace destructor with: ~this() { b.close; delete b; writefln("~C"); }}; int main() { { scope auto x = new C; } writefln("finished"); return 0; }You *could* do all the deletions in the destructors, but then you need to make damn sure your objects won't _ever_ be deleted by the GC. P.S. Ideally, of course, you'd be allowed to declare members as 'scope', so that they always get deleted when the referencing object is. Unfortunately, this is not currently allowed. (A way to implement this would be to 'inline' scoped members)
Jan 28 2007
P.S. Ideally, of course, you'd be allowed to declare members as 'scope', so that they always get deleted when the referencing object is. Unfortunately, this is not currently allowed. (A way to implement this would be to 'inline' scoped members)It seems like this feature would beat the .NET Framework's disposal/finalization approach. Would it be hard to implement in the compiler?
Jan 29 2007