Will I Am
Will I Am

Reputation: 2672

Generic alternative to Execute Around Method pattern

I was looking for an implementation of the Execute Around method pattern in scala, and found the following (with my minor mods):

class Resource private() {
  private def dispose() { println("Cleaning up...") }

  def example = {
      println("Function body")
  }

}
object Resource {
  def using(codeBlock: Resource => Unit) {
    val run = new Resource
    try {
      codeBlock(run)
    }
    finally {
      run.dispose()
    }
  }
}


Resource.using { run =>  run.example }

Then I had second thoughts about using it for my particular application, since that's a lot of boilerplate code in all my classes.

I was wondering if the more experienced scala gurus were able to create a similar pattern, and wrap an entire object, calling a cleanup method when the object goes out of scope? This would be similar to the C# using() block, and I'd implement it by mixing in a Disposable trait to the objects that would support this method?

Example goal:

trait Disposable { def dispose }
class a extends Disposable

[some helper object unrelated to a?].using (a) { 

} // automatically call a.dispose() at end of scope?

Upvotes: 0

Views: 205

Answers (1)

Angelo Genovese
Angelo Genovese

Reputation: 3398

From this blog post you can implement something like Java's try with resources this way:

class Loan[A <: AutoCloseable](resource: A) {
  def to[B](block: A => B) = {
    var t: Throwable = null
    try {
      block(resource)
    } catch {
      case x: Exception => t = x; throw x
    } finally {
      if (resource != null) {
        if (t != null) {
          try {
            resource.close()
          } catch {
            case y: Exception => t.addSuppressed(y)
          }
        } else {
          resource.close()
        }
      }
    }
  }
}

object Loan {
  def loan[A <: AutoCloseable](resource: A) = new Loan(resource)
}

you would use it like this:

loan (new PrintWriter(new File("file"))) to (_ println "Hello world!\n")

Using the Java AutoCloseable interface for this means that your objects can be used in a Java try-with-resources block and that you can use your helper with standard Java AutoCloseable things like IO streams.

Upvotes: 2

Related Questions