4 ms·
The salient point from the parent comment was that “using” assumes the resource is an Object. The core value prop of both “using” or “defer” is that a single s
by computomatic 3y ago
The salient point from the parent comment was that “using” assumes the resource is an Object.
The core value prop of both “using” or “defer” is that a single scope can manage the lifetime of some resource while child scopes interact with that resource.
“Using” assumes that resource is a local object but that’s rarely actually the case - as in the example of a DB connection - it’s just how OOP represents it.
A good counter-example would be if I need to manage a resource via an API. Maybe one request creates the resource and another tears it down. (Eg, begin a transaction and then commit it). “Using requires me to implement a new class to represent this resource - that’s OOP at its finest - whereas “defer” allows just doing the thing (and works equally well for objects)
- Timon3 3y agoThere is no need for you to create a new class to represent a resource. Javascript doesn't require objects to be instances of specific classes, so you can just return an object with the dispose method while only using it as a container. Even when using Typescript there is no need to add a new class, a new type declaration is more than sufficient. Just because it's on objects doesn't mean it's OOP.
- Dylan16807 3y ago> “Using” assumes that resource is a local object but that’s rarely actually the case - as in the example of a DB connection - it’s just how OOP represents it. Can you elaborate on this more? It would be hard to represent a DB connection without an object somewhere (or a closure that's effectively the same thing), and I don't understand how local or not comes into play. > Using requires me to implement a new class to represent this resource It just requires you to set a key. You could also have a function to add it or do it locally. Locally setting up Symbol.dispose does require more boilerplate than `defer`. But if the dispose is built into the object then `using` is less boilerplate than `defer`. And if you use a function to add the disposal, `using` with an extra function call is also less boilerplate than `defer`.
- _old_dude_ 3y agoDefer is more general than using, you can use it for other use cases, for logging logger.log("start") defer logger.log("exit") ... for keeping alive a reference (because you need to call C code) global.keepalive = myvar defer global.keepalive = undefined ... // call C code here etc
- Dylan16807 3y agoThose seem like things you'd do multiple places and it would be a good idea to make them into a function. If you have a one-off, defer is nicer looking but using is perfectly capable of doing the job: function defer_it(callback) { return { [Symbol.dispose]: callback }; } // will look better with using void using _ = defer_it(()=>logger.log("exit")); Or use DisposableStack() as another comment in this thread mentions.