4 ms·
Many modern languages have a convenient solution for those cases as well: Python has the "with" statement combined with context managers; C# has the "using" blo
by ptx 12y ago
Many modern languages have a convenient solution for those cases as well: Python has the "with" statement combined with context managers; C# has the "using" block with the "IDisposable" interface that does essentially the same thing; even Java recently got its corresponding "try-with-resources".
Before those were introduced we had try/finally which works equally well but is slightly more verbose.
- AnimalMuppet 12y agoYes, you can do this with try/finally. But if you have an object that has an open file as a member, then you open the file in the constructor, and then use the open file in the member methods, and then... what? You may have a scope that you are exiting where that object becomes irrelevant, but it may be several layers away. Having to close that object's handle in a finally in that scope seems likely to be forgotten at least some of the time.
- ptx 12y agoThat "scope that you are exiting ... several layers away" is where you put the try/finally. If an object has resources to dispose of (such as an open file), it should implement (to use C# as an example – it looks similar in Python and Java) the IDisposable interface, which allows you to do either: MyFileWrapperObject obj = ...; try { foo(); bar(); ... } finally { obj.Dispose(); } or: using (MyFileWrapperObject obj = ...) { foo(); bar(); ... } Or to take a Python example from what I'm working on right now: with open("something.json") as f: data = json.load(f) The file will automatically be closed at the end of the "with" block. Just like in C#, this feature can be used for any kind of resource, not just files.
- AnimalMuppet 12y ago> That "scope that you are exiting ... several layers away" is where you put the try/finally. Yes, I know that it's where you're supposed to put the try/finally... if you remember. Each time. And if you move the action in the finally clause if the variable changes scope or lifetime. Destructors are considerably cleaner than this approach. You just put the close in the destructor, and let it do its job.