implicit.ly

Scala software, hot off the presses

scala-arm 1.0

The scala-arm 1.0 release makes a few stabilizing changes to the API:

  • Removed the CanSafelyTranslate implicit hook for map/flatMap methods. ManagedResource objects are now properly Monadic.
  • The toTraversable method now takes implicit evidence that the resource is traversable. This can also take a function from the reosurce to a traversable.
  • The Resource type trait now specifies which exceptions cannot be ignored vs. which ones can safely be captured temporarily to close a resource.
  • Had to remove 2.9.0 and 2.9.0-1 versions temporarily due to strange scaladoc bug that was fixed in 2.9.1

Scala Automatic Resource Management

scala-arm is an automatic resource management library for Scala. The scala-arm library provides equivalent and improved fucntionality to Java 7's ARM.

Basic Usage

The Scala ARM library provides three "modes" of operations:

  • Imperative style resource management functions.
  • A monadic style resource management class.
  • A delimited continuation style API.

Imperative Style

The Scala ARM library allows users to ensure opening closing of resources within blocks of code using the managed method. This is easiest to accomplish with a for expression and the managed method defined on scala.resource:

import resource._
for(input <- managed(new FileInputStream("test.txt")) {
  // Code that uses the input as a FileInputStream
}

Monadic Style

The scala-arm library defined a monadic like container ManagedResource. This container defines map and flatMap interfaces. It can be constructed using the managed method defined on scala.resource. The map and flatMap methods are defined specially, but in generally they will do what you expect them to.
The map method will take a transformation of the raw resource type and return a new managed resource object of the transformed type. Let's see an example:

import resource._
val first_ten_bytes = managed(new FileInputStream("test.txt")) map { 
   input =>
     val buffer = new Array[Byte](10)
     input.read(buffer)
     buffer
}

This constructs a new resource that will obtain the first ten bytes of a file when aquired, each and every time. This allows you to build up behavior inside of a ManagedResource monad before attempting to acquire and execute the behavior. This is an excellent way to construct the means of querying for data and obtaining it fresh when needed.

Delimtied Continuations

The scala-arm library also supports using delimited continuations. This is done via the reflect method on ManagedResource. This can be used to "flatten" the nested blocks required to use resources. The best example is the and method defined on scala.resource. This method can be used to combine two resources into a single ManagedResource class containing a tuple of the two resources. It will jointly open and close both resources. The code is below:

import resource._
def and[A,B](r1 : ManagedResource[A], r2 : ManagedResource[B]) = 
    new ManagedResource[(A,B)] with ManagedResourceOperations[(A,B)] {
      override def acquireFor[C](f : ((A,B)) => C) = withResources {
        f( (r1.reflect[C], r2.reflect[C]) )
      }
    }