On Wed, 2015-10-28 at 16:02 +0100, Erik van Velzen wrote: > I didn't see how it could be generalized but your example clears that up.
Quick attempt of a generalization:
abstract class AbstractRAIIGuard {
private $succeeded = false;
protected abstract function fail();
protected function success() {}
public function succeed() {
if (!$this->succeeded) {
throw new RAIIAlreadyMarkedAsSuccessfulException();
}
$this->success();
$this->succeeded = true;
}
public function __destruct() {
if (!$this->succeeded) {
$this->fail();
}
}
}
class CallbackRAIIGuard extends AbstractRAIIGuard {
private $success;
private $fail;
public __construct(callable $fail, callable $success = null) {
$this->success = $success;
$this->fail = $fail;
}
protected function fail() {
call_user_func($this->fail());
}
public function success () {
if ($this->success) {
call_user_func_array($this->success, func_get_args());
}
}
}
class DBRAII extends AbstractRAII {
private $db;
public function __construct(DB $db) {
$this->db = $db;
$db->begin();
}
protected function fail() {
$this->db->rollback();
}
public function success () {
$this->db->commit();
}
}
function foo(DB $db) {
$guard = new DBRAII($db);
// or using the more generic class
$guard = new CallbackRAIIGuard(
[$db, "rollback"], [$db, "commit"]
);
// ....
$guard->succeed();
}
johannes
signature.asc
Description: This is a digitally signed message part
