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