scope + destructor with Exception parameter for RAII

Leandro Lucarella llucarella at integratech.com.ar
Tue Nov 28 11:57:19 PST 2006


What do you think of adding an optional parameter (exception) to the 
destructor, defaulting to null, to indicate the destructor was called 
then unwinding because an exception was thrown? Then you can almost 
forget about scope(exit/success/failure) and you have a RAII as complete 
  as Python's 'with' statement.

So you can do something like:

class Transaction
{
	Database db;
	public:
	this(Database d) { db = d; db.begin(); }
	~this() // success
	{
		db.commit();
	}
	~this(Exception e)
	{
		db.rollback();
	}
	// ...
}

scope Transaction t = new Transaction(db);

This concept could be extended to have as many destructors as you want, 
to handle different kind of exceptions, like:

class Transaction
{
	// ...
	~this() // success
	{
		db.commit();
	}
	~this(DatabaseException e)
	{
		db.rollback();
		// some recovery code
	}
	~this(AnotherException e)
	{
		db.rollback();
		// some other stuff
	}
	~this(Exception e)
	{
		db.rollback();
	}
}

I find it a little ugly and error prone =)
If, for example, you have to use scope(exit/success/failure) you have to 
  add yourself the finalization code on every use:

Each time you want to use a transaction (for example) you have to write:
Transaction t = new Transaction(db);
scope(failure) db.rollback();
scope(exit) db.commit();
// ... code

If you forget one scope(...) db.xxx(); you hit a bug. On the other hand, 
if you could just use:
scope Transaction t = new Transaction(db);

The code is simpler, less error prone, and plus you have all the 
Transaction logic in the transaction object, not in the code that uses 
the transaction.

Opinions? Factibility?

-- 
Leandro Lucarella
Integratech S.A.
4571-5252



More information about the Digitalmars-d mailing list