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]

Reply via email to