The ‘using’ control structure in 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.

 

 

Back to top

Introduction

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

/**
 * 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. More on this shortly.

Back to top

Using the ‘using’ control structure

That code may not make much sense on its own, so here's an example of how I used it in an application:

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.

Back to top

How the ‘saveStock’ method works

The saveStock method takes advantage of the using control structure and my MongoFactory (not shown). This code does the following:

  • Gets a MongoConnection from the MongoFactory.
  • Calls the save method on the MongoCollection instance.
  • Automatically closes the MongoConnection, courtesy of the using control structure.
Back to top

How the using control structure works

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

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 types.
  • A can be an instance of any class that has a close() method. (This is known as a structural type in Scala.)
  • B can be any type.
  • The f parameter is something that takes a type A and transforms it to a type B.
  • The body of the code is very simple, it executes f with param, and calls the close() method on param, regardless of whether f(param) throws an exception.

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 MongoCollection instance. The result of that save method call is a WriteResult instance, though I don't use that instance in this example.

Back to top

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.

You can find an excerpt of David Pollak's book at this URL on Google Books:

You can also find Mr. Pollak's Beginning Scala book here on Amazon.

Back to top

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.