On 5 November 2025 23:58:52 GMT, Bob Weinand <[email protected]> wrote:

>However, I still think the proposed approach is dangerous with respect to 
>forgetting the exitContext() call. When using manual handling. But yes, I 
>agree, that's a much more manageable concern.
>And the onus of handling duplicate enterContext() and multiple exitContext() 
>calls still lies on the implementer. The RFC does zero effort at addressing 
>this.

I think the relationship to Iterators is significant: if you put an iterator in 
a variable, it's perfectly possible to use it in two different foreach 
statements, or manually call the interface methods, and get very confusing 
results.

But most of the time, you don't take a reference to the iterator at all, and 
the same would be true of Context Managers:

foreach ( $foo->iterate() as $item ) { ... }
with ( $foo->guard() as $resource ) { ... }


That said, it seems like it would be easy enough to add a mandatory state check 
- a boolean property on the interface, and a check in the de-sugared code:

if ( ! $__mgr->canEnter ) { throw SomeError; }
$__mgr->canEnter = false; 

That would also give the implementation a choice of whether to reset it on 
exit, or make the object strictly single use.


That doesn't stop you manually calling the enterContext and exitContext methods 
in unintended ways, but that's actually true of RAII or Disposable designs, at 
least in PHP: there's nothing stopping you calling __construct or __destruct as 
normal methods, and causing all sorts of unintended behaviour.




Rowan Tommins
[IMSoP]

Reply via email to