Re: [RFC] Context Managers, v2

From: Date: Fri, 13 Nov 2026 23:53:15 +0000
Subject: Re: [RFC] Context Managers, v2
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-133100@lists.php.net to get a copy of this message
Hi Larry, On Fri, Nov 13, 2026 at 3:21 PM Larry Garfield <larry@garfieldtech.com> wrote: > Hi folks. Based on the feedback and problems with the previous Context > Managers RFC, Arnaud and I have a new approach to present: > > https://wiki.php.net/rfc/context-managers-v2 > > It basically swaps the two-method approach in favor of "it's a generator, > you're welcome." The result is, I think, both simpler and more flexible, > and resolves a number of other issues as well. More details in the RFC. > > There is a linked implementation, though Arnaud warns it's only partially > complete so go easy on it. :-) But the design in the RFC is all ready for > review. > > -- > Larry Garfield > larry@garfieldtech.com Some feedback on the current RFC draft 1. The behavior section says > When a using expression is encountered, the GENERATOR is first evaluated to > ensure it is a Generator object. If it is not, an Error is thrown. (See the > section below regarding resources, however.) Can you include some mention of ContextManager here, since GENERATOR can be evaluated to a ContextManager that is then called to get the generator. 2. I'm wondering about what happens if the generator throws an exception. Specifically, it could throw after yielding, but before it terminates, i.e. when it resumes execution after the BODY finishes, returns, or throws. Looking at the "Implementation details" example desugaring, it seems like that exception would just be silently ignored, but I don't see that anywhere in the specification. 3. A number of other things trigger errors, but for generators that yield with keys, the keys are just silently ignored - did you consider throwing an error for that too? 4. I'd prefer to not add special syntax for this in try-catch, it looks like it just saves 3 characters (opening {, closing };) plus any whitespace that the developer wants, and it looks a bit odd to me. We can always add this later if it becomes a common pattern. It also means that the returned value from the using block cannot be stored anywhere. 5. Speaking of the returned value from the using block, can you confirm that NoDiscard will be handled properly? Consider a modified version of the file_for_writing function given as an example: ```php /** Returns true if everything succeeded, and false otherwise */ #[\NoDiscard('as failures should be handled')] function file_for_write(string $file) { $fp = fopen($file, 'w'); if ($fp) { try { yield $fp; // If this line is reached, then the using didn't throw an exception return true; } catch (\Exception $e) { log('The file failed.'); } finally { fclose($fp); } } // Either fopen() didn't succeed, or it succeeded but the using block // had an exception. return false; } ``` for the example ```php using (file_for_write('file.txt') => $fp) { foreach ($someThing as $value) { fwrite($fp, serialize($value)); } }; ``` the returned value from file_for_write isn't used and should trigger a warning. 6. Is there a way for the generator to specify that the *yielded value* should not be discarded? The current RFC text says > If no VAR is specified, the yielded value is ignored. and while NoDiscard would highlight the ignoring for a function return, it doesn't for generator yields. Thanks, -Daniel

« previous php.internals (#133100) next »