The point is missed

Museum of public mistakes and unfinished projects

Scala Nugget – implicits to make java blend into Scala

with 2 comments

Most of my posts related to Scala so far have been quite long and unpolished I have intentionally kept them that way since I wanted to give a feel for what i is really like to make the shift, including the dead ends.

During the work of converting Java to Scala I have stumbled over some things that I found to be extra cool, nuggets. I’ll try to post them here from time to time.

The first nugget is about implicits. Implicits are so cool that I think I will shoot myself in the foot with them many times so let’s start now. One piece of java-code that I converted looked for module descriptions on the class-path. The code looked something like this:

   private void loadModules() throws IOException {
        Enumeration<URL> modules = Thread.currentThread()
                .getContextClassLoader().getResources("ap.module");
        while (modules.hasMoreElements()) {
            URL element = modules.nextElement();
            ...
        }
    }

We ask the class loader to give us all the ap.module files it can find. The class loader will give back an enumeration of URL:s to the resources. Ever been in a situation where you wished that an enumerator was an iterator?

Well, let’s look at the same code in Scala:

    private def loadModules():Unit = {
       val modules = Thread.currentThread().getContextClassLoader().getResources("ap.module");
       modules.foreach(moduleUrl => {
          ...
       }
    }

Nice, but it doesn’t compile:

value foreach is not a member of java.util.Enumeration[java.net.URL]

Ok, let’s wrap the enumeration in a Scala Iterable. First create the wrapper:

class RichEnumeration[T](enumeration:Enumeration[T]) extends Iterator[T] {
  def hasNext:Boolean =  enumeration.hasMoreElements()
  def next:T = enumeration.nextElement()
}

Observe how I can just assign the methods on the wrapped enumeration to the corresponding ones in my iterable. Itearable is a Trait so you can add this capability to any class with about the same effort. Well, let’s use the RichEnumeration:

    private def loadModules():Unit = {
       val modules = new RichEnumeration(
                    Thread.currentThread().getContextClassLoader().getResources("ap.module"));
       modules.foreach(moduleUrl => {
         ...
       }
    }

Ok, that was slick. Now to the final magic trick:

    implicit def enumerationToRichEnumeration[T](enumeration:Enumeration[T]):RichEnumeration[T] = {
       new RichEnumeration(enumeration)
    }

    private def loadModules():Unit = {
       val modules = Thread.currentThread().getContextClassLoader().getResources("ap.module");
       modules.foreach(moduleUrl => {
         ...
       }
    }

Wow, since we call foreach on the enumerator, Scala, before failing looks around for any implicit conversions it can make. Our implicit enumerationToRichEnumeration function converts Enumerations to RichEnumerations and the scala compiler sees that RichEnumerations are Iterables and Iterables have a foreach-method. So Scala can implicitly use it.

With that piece of code I can treat any enumeration as an Iterable, scala will take care of the conversion for me.

Dangerously cool!

About these ads

Written by johlrogge

September 11, 2008 at 9:06 pm

Posted in java, scala

Tagged with , ,

2 Responses

Subscribe to comments with RSS.

  1. [...] found implicits worth it’s own little entry here Possibly related posts: (automatically generated)Buildr – Keeping up with the latest and [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: