Thursday, October 29, 2009

Reflective Calls in Scala

Scala 2.8 contains two experimental features to reflectively invoke methods. Are these cool?

import scala.reflect.RichClass._

val hello = "hello"
val helloStartsWith = classOf[String].reflectiveCall(hello, "startsWith")
val b1: Boolean = helloStartsWith("hell")
val b2: String = helloStartsWith("heaven") // ClassCastException (Boolean->String)
val b3 = helloStartsWith("blah") // ClassCastException (Boolean->Nothing)

import scala.reflect.Invocation._

val team: AnyRef = "team"
val any = team o 'contains("I") // returns 'Any'
val b4: Boolean = team oo 'contains("I") // ok
val b5 = team oo 'contain("I") // ClassCastException (Boolean->Nothing)

The methods called using "o" return "Any". Both reflectiveCall(...) and the "oo" version return the inferred type. Note that this doesn't relieve you from knowing the expected result type, or further reflecting it and casting. This is shown in the runtime errors with b2, b3, and b5.

EDIT: This post was accurate for the nightly 2.8 release when it was written, but this code appears to have been removed from the latest 2.8 betas.

No comments: