Re: [RFC][Discussion] use construct (Block Scoping)
| From: | Rowan Tommins [IMSoP] | Date: | Mon, 10 Nov 2025 18:53:10 +0000 |
| Subject: | Re: [RFC][Discussion] use construct (Block Scoping) | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-129190@lists.php.net to get a copy of this message | ||
On 10/11/2025 13:24, Arnaud Le Blanc wrote:
As I'm seeing it, a File object that was explicitly closed would throw an exception like "FileIsClosedError". It would indicate a lifetime bug that needs to be fixed, not something that should be handled by the program. This is reasonable, as closing is a clear intent that the resource should not be used anymore. This is not an exception that needs to be handled/checked. Under these intentions, leaving the resource open (for the reason it's still referenced) and allowing writes to it would be much worse.C# / .net has an ObjectDisposedException for this purpose. The documentation does indeed advise against catching it:
In most cases, this exception results from developer error. Instead of handling the error in a |try|/|catch| block, you should correct the error, typically by reinstantiating the object.https://learn.microsoft.com/en-us/dotnet/api/system.objectdisposedexception Note that using() does not prevent this. For example, in the following, the using() block will implicitly call ms.Dispose(), but the variable is still in scope. MemoryStream ms= new MemoryStream(16); using (ms) {
ms.ReadByte();} ms.ReadByte(); // throws ObjectDisposedException Similarly, additional references to the object can be made with lifetimes which exceed the using() block: MemoryStream ms_outer; using (MemoryStream ms_inner = new MemoryStream(16)) {
ms_inner.ReadByte(); ms_outer = ms_inner;} ms_outer.ReadByte(); // throws ObjectDisposedException In Hack, I believe both of these would be rejected by the compiler, because any object implementing IDisposable is subject to strict usage restrictions. -- Rowan Tommins [IMSoP]