5 ms·
> While recommended, `with` isn't always applicable. For example, assume you have an object that encapsulates some sort of a database that has to be committed a
by ChrisSD 8y ago
> While recommended, `with` isn't always applicable. For example, assume you have an object that encapsulates some sort of a database that has to be committed and closed when the object ends its existence. Now suppose the object should be a member variable of some large and complex class (say, a GUI dialog, or a MVC model class). The parent interacts with the DB object from time to time in different methods, so using `with` isn't practical. What's needed is a functioning destructor.
Isn't the issue with __del__ that you have no idea when or even if it will ever run? This is always a problem with destructors, no? I know I'm slightly too paranoid about resource management but I get nervous with that lack of control.
- deleted 8y ago[deleted]
- MereInterest 8y agoDepends on the language, but you are correct that in GC languages it off nondeterministic when the destructor is called. I've read some articles that make a distinction between C++ destructors, which do occur deterministically, and finalizers in GC languages.
- masklinn 8y agoThis is not just a language thing: CPython is reference-counted, so `__del__` is deterministic (in the absence of cycles at which point all bets are off, especially since the cycle breaker bails out then) however pypy or jython are not refcounted, and `__del__` is thus very much non-deterministic. In fact, this implementation divergence is most of the reason why `with` got added to the language, the reliance on reference counting for deterministic release of resource was ultimately seen as an issue for alternative implementations as they'd face non-memory resource exhaustion issues when trying to run existing software.
- deleted 8y ago[deleted]
- ChrisSD 8y agoEven when destructors are deterministic, they still may run later than you realise or not at all. For example, the Rust docs list some platform specific examples of when the 'drop trait' (aka destructor) may not run for thread local values[0]. There are also circular references or simply another object holding a reference (directly or indirectly) that isn't clear from the context. The `with` statement at least seems to clear up a lot of potential ambiguity if nothing else. [0] https://doc.rust-lang.org/std/thread/struct.LocalKey.html#platform-specific-behavior https://doc.rust-lang.org/std/thread/struct.LocalKey.html#pl...
- chronial 8y agoThis is stated even more clearly here: https://doc.rust-lang.org/std/mem/fn.forget.html#safety https://doc.rust-lang.org/std/mem/fn.forget.html#safety > forget is not marked as unsafe, because Rust's safety guarantees do not include a guarantee that destructors will always run. For example, a program can create a reference cycle using Rc, or call process::exit to exit without running destructors. Thus, allowing mem::forget from safe code does not fundamentally change Rust's safety guarantees.