using

NEM 26 Aug 2006: C# has a nice little construct for automatically closing a resource once you are finished with it. Here's a Tcl version of this using command:

proc using {varName chan script} {
    upvar 1 $varName var
    set var $chan
    set rc [catch { uplevel 1 $script } result]
    catch { close $chan }
    return -code $rc $result
}

Which you can then use like:

using fd [open somefile.txt] { puts [read $fd] }

or

foreach host $hosts {
    using sock [socket $host $port] { ... do stuff on $host ... }
}

See also Playing with with and withOpenFile.


RS I'm not so happy with the name using: it means other things in other languages (like with packages or namespaces) and does not indicate that it's for channels. Something like LISP's WITH-OPEN-FILE might be clearer to understand :)

KPV Actually the C# construct is quite useful and not just for files but for many types of objects which grab some scarce resource. (Technically, it works with any object which implements the IDispose interface).

NEM: Yes, the name is more appropriate in C# where it refers to any kind of (disposeable) resource. I limited it to channels in Tcl for simplicity. Despite the potential ambiguity of the name, in actual usage it seems pretty clear to me. Ideally, you could put it in the chan ensemble.


CMcC 2007-1-13: jcw's oomk interface to metakit has a similar concept for scoping. the as method on some objects constructs an instance and assigns its name to a variable in the calling namespace. Using trace, the lifetime of the constructed instance is associated with that of the scoped variable: when the unset trace fires, the object's destructor is called. Thought it might be relevant to mention.


AMG: This reminds me of the sqlite transaction subcommand: [L1 ]. "The transaction is committed when the script completes, or it rolls back if the script fails."