Getting into the new Scala’s 2.10 Reflection API

The newer version of Scala brings us some new features. In this post, Simon Ochsenreither listed many of these new things. One of  the most expected, at least for me,  is the new Reflection API. In my last project at Caelum, we faced a lot of problems using Java’s Reflection API to discover things that just existed in a Scala class. For example, we needed to know if a method was implicit or not and this information was not clearly pointed at the bytecode. In order to solve this problem, we had to use the scalap library and I can tell, the code is not beautiful.

So my point here is just that, show you how to use the new Reflection API to discover if a method is or not a implicit. The code must be a starting point to do whatever you might need with the rest of the API.

To get started I was looking for a way to get information about the class, such as methods implicitness, existence of companion objects and so on. So I created an Object with an implicit method just to test:

 object Pimps{
    implicit def pimp(str:String) = new {
       def test = println("hello")
    }
 }
 

Now I need to get information about this class, all the traits that you must know to work with Scala’s Reflection are at Scala’s github repository, and that was my starting point. The Mirror trait is the entry point of the api, its implementation can be found here. So let’s get started retrieving all the informations about our class. Here is the code:

val aType:Type = Mirror.typeOfInstance(Pimps)

Now we have the Type instance of our class. This object provides informations about your class, for example we can pick all the members. Let me show you the code:

 val members:List[Symbol] = aType.members
 

The Symbol trait is the abstraction of everything that you have in your class, constructors, methods, variables and the class declaration itself. And, at least for me, this was my savior. With an instance of Symbol is possible to get information about the Scala code. For instance, let’s filter all the Symbols that contains an implicit modifier in our Pimps class:

val justImplicits = members.filter(member => member.hasModifier(Modifier.`implicit`))

I think this is a good starting point to test the new API. All the code was tested in REPL with the 2.10 version, milestone 2. Also, there is a gist with the example code. Don’t forget the imports :).

Thanks to @adrianoalmeida7 for kindly reviewing this post.

Advertisements

4 thoughts on “Getting into the new Scala’s 2.10 Reflection API

  1. IMO they should have either used a type called Member (instead of Symbol) or had the reflection call be aType.symbols.

  2. Nice post. I wonder why they decided to have the horrible backticks, like Modifier.`implicit`, instead of using for example upper case names as is down in the Tree DSL (Def instead of `def` etc.).

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