Simple Scala pattern for "using/try-with-resources" (Automatic Resource Management)

clay picture clay · Sep 3, 2014 · Viewed 15.4k times · Source

C# has using with the IDisposable interface. Java 7+ has identical functionality with try and the AutoCloseable interface. Scala lets you choose your own implementation to this issue.

scala-arm seems to be the popular choice, and is maintained by one of the Typesafe employees. However, it seems very complicated for such a simple behavior. To clarify, the usage instructions are simple, but understanding how all that code is working internally is rather complex.

I just wrote the following super simple ARM solution:

object SimpleARM {
  def apply[T, Q](c: T {def close(): Unit})(f: (T) => Q): Q = {
    try {
      f(c)
    } finally {
      c.close()
    }
  }
}
  • Is there any benefit to something like simple-arm? It seems all the extra complexity should deliver extra benefit.
  • Normally, it is highly preferable to use a public, open source, library that is supported by others for general purpose behavior over using custom code.
  • Can anyone recommend any improvements?
  • Are there any limitations to this simple approach?

Answer

cchantep picture cchantep · Sep 3, 2014

Your approach with a single simple loan pattern is working fine as long as you don't need to work with several resources, all needing to be managed. That's allowed with scala-arm monadic approach.

import resource.managed

managed(openResA).and(managed(openResB)) acquireFor { (a, b) => ??? }

val res = for {
  a <- managed(openResA)
  b <- managed(openResB)
  c <- managed(openResC)
} yield (a, b, c)

res acquireAndGet {
  case (a, b, c) => ???
}

Main functions to know in scala-arm is resource.managed and .acquired{For,AndGet}, not really complex btw.