smalltalk

Cleaning up external resources

February 13, 2006 11:31:32.009

Bob Congdon has a post up on the difficulties of cleaning up external resources in Java if exceptions get thrown while they are in use. He points to a C# feature that ensures that such resources will be finalized, the using statement:


using (TextWriter tw = File.CreateText("log.txt")) {
      tw.WriteLine("Foo");      
      // Other stuff  
} 

Apparently, the compiler expands that. In Smalltalk, we don't need a language feature for that - we have the #ensure: method. It looks like this:


stream := 'someFile' asFilename writeStream.
[stream nextPutAll: 'Foo'.
"other code here"]
     ensure: [stream ifNotNil: [stream close]].

#ensure takes a block (closure) as an argument, and will execute regardless - if there are exceptions inside the block it's sent to or not. It's a very clean way to make sure that necessary code runs, when you aren't particularly concerned with the exact nature of any exceptions that pop up.

Comments

C# expansion

[] February 13, 2006 12:29:07.726

The using(...) you list above is really sugar for the more verbose try {} finally {}

Unless I'm forgetting my Smalltalk, the ensure: block essentially translates to try{} finally{} in C# (and in Java).

Also in Ruby

[Mr. Big] February 13, 2006 13:13:17.727

[] February 13, 2006 13:51:35.770

This should be part of the standard library

[Wilkes Joiner] February 13, 2006 21:32:37.616

In Ruby you can say:

File.open('somefile.txt', 'w') do | f |

... do some stuff with the file ...

end

This guarantees that the file will be closed. There is no reason that this can't be done in Smalltalk:

File class>>openForWriting: aString do: aBlock

stream := aString asFilename writeStream.

aBlock 
    value: stream; 
    ensure: [stream ifNotNil: [stream close]].
 
BTW, is there a way to turn off this editor? 

It's actually easier in Java

[Matthias] February 14, 2006 2:29:04.059

Bob just hasn't figured it out. You put the try after the variable declaration, it becomes much less clunky than his version and no less right:

OutputStream os = new FileOutputStream("someFile");
try { os.write(bytes); } finally { os.close(); }

The thing that is better about the C# version is that the variable doesn't pollute the scope.
BTW, this editor stinks ...

Re: It's actually easier in Java

[Christian Ullenboom] February 16, 2006 2:43:28.462

Sorry Matthias but you need a second (ugly) try/catch around close (or a throws in the method definition, o.k.)

OutputStream os = new FileOutputStream("someFile"); 
try { os.write(bytes); } finally { try {os.close(); } catch (IOException e ){} }
This isn't nice :-( 

BTW: I like IOUtils from Jakarta Commons IO.

 Share Tweet This
-->