-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to prevent consumer code from accessing the dispose method #69
Comments
I'd rather not introduce extra complexity that might deter usability. Explicit cleanup is already part of the public API of many runtimes and packages in JS already (see Motivations in the explainer). The majority of the languages which are referenced as prior art allow consumers to explicitly dispose:
Iterators are only one of many mechanisms that employ resource cleanup (via That said, the provider of a resource can model their API in any way they choose. If you wish to yield values that are disposed at the end of iteration without providing access to cleanup, that is completely up to your design. For example: function * resourceProducer() {
const resource = ...; // some resource to yield. does not have a [Symbol.dispose]
const cleanup = () => { ... }; // cleanup mechanism for resource
using const holder = new Disposable(cleanup); // registers cleanup step
yield resource; // provides resource that can't be directly disposed.
...
} // `holder` is disposed when `resourceProducer()` exits.
// consume resources
for (const resource of resourceProducer()) {
// resource not directly disposable
} // `resource` cleanup handled by `resourceProducer` when iterator is exhausted or `.return()`/`.throw()` is called. The addition of |
The problem with this is that the Personally I would like to see something that is similar to // resourceProvider is a generator
using (const resource of resourceProvider()){
// This block is guaranteed to only run once, no matter what the provider does
} A nice advantage of this is that you wouldn't have to introduce a new Disposable class or symbol to the language, since iterators will do the job - and can accomodate resources with or without a disposable method: function * openFile(path){
const fh = getFileHandle(path);
try {
yield new File(fh);
} finally {
releaseFileHandle(fh);
// Equally this could be fh.destroy() if you want
}
} I understand you concern about not adding too much complexity, but I don't think my concern is trivial either - forcing data into a specific structure in order to use a particular language feature, even if that structure doesn't make sense from a logical or security point of view. I shouldn't have to leak information about how to dispose an object if it's not relevant to the consumer. |
I don't believe that resource management should be tied to iterators. Iterators are the wrong level of abstraction and only some iterators are "disposable" (via
This is often exactly how new language features are supported in both JS and other languages. For an object in JS to be treated as a resource either using Using iterators purely to manage lifetime adds even more responsibilities to an already overloaded concept. Some Iterators may be disposable, and some disposables may be iterated, but that primarily shows that these are two very loosely related but different concepts. I'm also not sure how a "security point of view" figures into this discussion either. Neither |
I will consider this issue as closed, but please let me know if you have any additional concerns. |
If I'm creating a resource to pass to other code, I don't necesarily want that code to be able to dispose the resource. Creation and disposal are, to me, concepts that are separate from the resource's actual usage, whereas the requirement of a 'dispose' symbol on the resource conflates the two concepts.
Have any other options been considered? Perhaps an iterator that yields the resource and disposes it afterwards (as developers are currently used to)
The text was updated successfully, but these errors were encountered: