Monday, February 13, 2006

Cleaning Up External Resources

James Robertson blogs about how easy it is to clean up resources in Smalltalk via #ensure: which is simply a message send to a block.
stream := 'someFile' asFilename writeStream.
[stream nextPutAll: 'Foo'.
"other code here"]
ensure: [stream ifNotNil: [stream close]]

But, I can't resist showing the Ruby version:
File.open("someFile", "r") do | stream |
#other code here
end

I love it. It takes the block one step further. The block in the Ruby code gets passed to the open where it "ensures" the stream is closed. Pretty clever. Of course, we can have the same thing in Smalltalk and it's usually something that I usually implement:
'someFile' asFilename readDuring: [:stream | "other code here"]

We simply implement #readDuring: like this:
readDuring: aBlock
| stream |
stream := self writeStream.
[aBlock value: stream] ensure: [stream close]

If we cracked open the Ruby source we would see something similiar to the above implementation. I love it when my language allows me to be concise from existing parts! Don't you? Closures rule!

No comments: