On 05/11/2025 22:38, Bob Weinand wrote:
I don't like that design, which effectively forces you to put safety
checks for all but the simplest cases onto the ContextManager
implementation.
And it forces the user to recognize "this returned object
DatabaseTranscation actually implements ContextManager, thus I should
put it into with() and not immediately call methods on it". (A problem
which the use() proposal from Tim does not have by design.)
I think you may have missed the key distinction between a "Context
Manager" (as designed by Python) and a "Disposable" (as used in C# and
others): the Context Manager is not the resource itself, it exists only
to meet the protocol/interface.
In this code:
with ( $dbConnection->transaction() as $handle ) {
$handle->execute('I am in the transaction');
}
$handle is *not* the value returned by $dbConnection->transaction(),
it's the value returned by $dbConnection->transaction()->enterContext().
One of the things that means is that if you just write
$foo=$dbConnection->transaction() you can't accidentally run any methods
on $foo, if all it has is enterContext and exitContext.
It also means you can trivially wrap values that have no idea about
context managers, without needing a load of extra proxy code; it's why
the RFC can include implicit handling for resources; and why the
generator example in the Future Scope section works.
--
Rowan Tommins
[IMSoP]