Erik van Velzen wrote on 28/10/2015 13:28:
     try {
         $scope = new ScopeGuard;

         $scope->onSucces(function() { logTransactionOne(); });
         $scope->onFailure(function() { rollbackTransationOne(); });
         doTransactionOne();

         $scope->onSuccess(function() { logTransactionTwo(); });
         $scope->onFailure(function() { rollbackTransactionTwo(); });
         $scope->onExit(function() { cleanupTransactionTwo(); });
         doTransactionTwo();
     }
     catch (\Throwable $e) {
         $scope->callFailureHandlers();
         throw $e;
     }
     finally {
         $scope->callExitHandlers();
     }

     $scope->callSuccessHandlers();

Did you see Johannes' suggestion re explicit success vs implicit failure?

$scope = new ScopeGuard;

$scope->onSucces(function() { logTransactionOne(); });
$scope->onFailure(function() { rollbackTransationOne(); });
doTransactionOne();

$scope->onSuccess(function() { logTransactionTwo(); });
$scope->onFailure(function() { rollbackTransactionTwo(); });
$scope->onExit(function() { cleanupTransactionTwo(); });
doTransactionTwo();

$scope->registerSuccess();


The ScopeGuard's destructor can now detect the condition:

if ( $this->success_registered ) {
   // Function reached checkpoint for this scope
   $this->callSuccessHandlers();
} else {
   // Function aborted early, due to a throw or early return
   $this->callExitHandlers();
}
$this->callExitHandlers();


No boilerplate throw-catch needed, works even if there is already a catch or 
finally within the function's definition.

In fact, I kind of want to use this somewhere now... ;)

Regards,
--
Rowan Collins
[IMSoP]


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to