The ‘using’ control structure from Beginning Scala (by David Pollak)

In David Pollak's book, Beginning Scala, he introduces a using control structure that is helpful in several ways. First, it can be used to automatically close any resource that has a close method. Second, it's a great example of how to create a custom control structure in Scala.

UPDATE: Don’t use this code in production. Instead, use the scala.util.Using object. This code and blog post is shown here for informational and educational purposes only.

David Pollak’s ‘using’ control structure

Here's the source code for the using control structure he created:

// this import is required when using reflection, like `using` does
import scala.language.reflectiveCalls

/**
 * From the book, Beginning Scala, by David Pollak.
 */
object Control {

  def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
    try {
      f(param)
    } finally {
      param.close()
    }

}

This is a clever bit of code that creates a new control construct you can use named using that we'll use to perform our inserts. If you're comfortable with the syntax shown, you can see that this construct automatically calls the close() method on the param it's given.

How the ‘using’ control structure works

Let's look at how the using control structure works. First, here's the source code again:

import scala.language.reflectiveCalls

object Control {

  def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
    try {
      f(param)
    } finally {
      param.close()
    }

}

Here's how the using method works:

  • A and B both define generic types.
  • A can be an instance of any class that has a close() method. (This type of definition is known as a structural type in Scala.)
  • B can be any type; no restrictions are specified.
  • The f parameter specifies a block of code that takes a type A as input and transforms it to a type B.
  • In the function body, f is executed with param as its input parameter inside the try block. When that finishes, or if it throws an exception, the close() method is called on param.

Next, here's another look at the code that calls the using method:

using(MongoFactory.getConnection) { conn =>
    MongoFactory.getCollection(conn).save(mongoObj)
}

The first parameter passed to using is MongoFactory.getConnection, which is an instance of MongoConnection. The MongoConnection class has a close() method, so it's legal to pass this instance in as the first parameter. The second parameter passed in is an anonymous function that takes the parameter of type A (the MongoConnection) and converts it to type B, which is the result of the save(mongoObj) method call on the MongoConnection instance. The result of that save method call is a WriteResult instance, though I don't use that instance in this example.

The ‘using’ control structure and the Loan Pattern

The using control structure implements something that’s known as the Loan Pattern. Basically a resource is loaned to some block of code, and then that resource is guaranteed to be closed. The following code demonstrates how to use using when reading from a file:

import Control._

object TestUsing extends App {
    using(io.Source.fromFile("example.txt")) { source => {
        for (line <- source.getLines) {
            println(line)
        }
    }}
}

Using ‘using’ with MongoDb and Casbah

As a quick note, here’s a complete MongoDb/Casbah example:

import com.mongodb.casbah.Imports._
import Common._
import Control._

object Insert extends App {

  // create some Stock instances
  val apple = Stock("AAPL", 600)

  // save them to the mongodb database
  saveStock(apple)

  // uses the 'using' control structure to automatically close the db connection
  def saveStock(stock: Stock) {
    using(MongoFactory.getConnection) { conn => {
       MongoFactory.getCollection(conn).save(buildMongoDbObject(stock))
     }
    }
  }
}

While I later learned that you don't need to close Casbah connections manually like this, this approach shows how to use the using method in your own code.

Summary

I hope this discussion of David Pollak's using control structure is helpful. If you need a control structure that automatically calls a close method on an object, or wanted an example of how to create your own control structure, I hope this has been helpful.