I have seen many examples of ARM (automatic resource management) on the web for Scala. It seems to be a rite-of-passage to write one, though most look pretty much like one another. I did see a pretty cool example using continuations, though.
At any rate, a lot of that code has flaws of one type or another, so I figured it would be a good idea to have a reference here on Stack Overflow, where we can vote up the most correct and appropriate versions.
Chris Hansen's blog entry 'ARM Blocks in Scala: Revisited' from 3/26/09 talks about about slide 21 of Martin Odersky's FOSDEM presentation. This next block is taken straight from slide 21 (with permission):
--end quote--
Then we can call like this:
What are the drawbacks of this approach? That pattern would seem to address 95% of where I would need automatic resource management...
Edit: added code snippet
Edit2: extending the design pattern - taking inspiration from python
with
statement and addressing:Managed
classThis is with Scala 2.8.
How about using Type classes
Here's James Iry solution using continuations:
Here are the solutions with and without continuations for comparison:
And here's Tiark Rompf's suggestion of improvement:
Daniel,
I've just recently deployed the scala-arm library for automatic resource management. You can find the documentation here: http://wiki.github.com/jsuereth/scala-arm/
This library supports three styles of usage (currently):
1) Imperative/for-expression:
2) Monadic-style
3) Delimited Continuations-style
Here's an "echo" tcp server:
The code makes uses of a Resource type-trait, so it's able to adapt to most resource types. It has a fallback to use structural typing against classes with either a close or dispose method. Please check out the documentation and let me know if you think of any handy features to add.
Another alternative is Choppy's Lazy TryClose monad. It's pretty good with database connections:
And with streams:
More info here: https://github.com/choppythelumberjack/tryclose
There is light-weight (10 lines of code) ARM included with better-files. See: https://github.com/pathikrit/better-files#lightweight-arm
Here is how it is implemented if you don't want the whole library: