What's the use case of clear?
Lutger
lutger.blijdestijn at gmail.com
Tue Aug 10 10:01:37 PDT 2010
django wrote:
> I read the recent discussion on the subject (TDPL: Manual invocation of
> destructor) but I still don't understand what is the use case clear() wants to
> cover?
>
> Assume for a moment that we have this class:
>
> class Connection {
> this() { connect(); }
> ~this() { if (connected) disconnect(); }
> void disconnect() { ... }
> ...
> }
>
> Now I see the following use cases:
>
> // The connection is closed at some later point if at all.
> var c1 = new Connection;
>
>
> // I want the connection closed at the end of the function.
> // Should be safe everytime.
> void foo() {
> var c2 = new Connection;
> scope(exit) c2.disconnect();
> ...
> }
>
>
> // I want the connection closed and memory released.
> // (I know what I'm doing)
> void bar() {
> var c2 = new Connection;
> scope(exit) {
> c2.disconnect(); // Even better, call the constructor.
> GC.free(c2);
> }
> ...
> }
>
> What's left for clear()? In which scenario would I like the default
> constructor called again?
>
> Thanks
Honestly I think that clear() as it does too much, but this is what I think was
intended:
Class Connection {
invariant() { assert( pool !is null); }
ConnectionPool pool = null;
bool isOpen = false;
this() {
pool = ConnectionPool.get();
enforce(pool !is null);
}
this(string connectionString) {
this();
connect(pool, connectionString);
isOpen = true;
}
~this() {
disconnect(pool, connectionString);
}
}
/* use case: although I do not really care the connection should at least be
closed when this object is collected
*/
auto c = new Connection(connectionString);
/* Now I want this too:
1 connection closed at the end of scope
2 isOpen will be reset to false
3 the pool Singleton reference must not be null
(2-3 are important when there may be other references to the connection that
attempt to use it)
*/
scope(exit)
clear(c);
/* I also want this scheme to be standardized, so that derived classes can more
easily hook up with the disposal scheme and client code does not have to look up
the documentation, check what the actual polymorphic type is, etc.
*/
class MyConnection : Connection { ... }
clear(myConnection); // also does its magic for Connection
clear() wants to solve all of these use cases by itself in a way that the class
implementor only has to implement a destructor and the user only needs to call
clear().
But imho it conflicts with some (more) important ones. Like in your example, you
do not expect to actually connect to the database when you clear() the
connection, it would a huge wtf! You also cannot rely on a destructor being
called once, nor can you check if an object has already been destructed (without
hacks). It is the whole point of clear() that you cannot do so, I think
More information about the Digitalmars-d
mailing list