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