mercredi 9 août 2017

Using Scala Reflection to Return a Typed Function

I am building an engine that will be dynamically driven by xml. I would like to be able to keep the engine code skinny and have other teams drop in jars that I can use their classes/objects and methods. Using reflection I am able to call methods dynamically but I can't pass them around as first class functions. Is there a way to return a typed reflected method in scala? I think it has something to do with type erasure but I am not sure. Thank you!

Main.scala

import scala.reflect.runtime.{universe => ru}

object Main {
  def reflectFoo(str: String): (Int) => Boolean = {
    val m = ru.runtimeMirror(getClass.getClassLoader)
    val module = m.staticModule("Reflect")
    val im = m.reflectModule(module)
    val method = im.symbol.info.decl(ru.TermName(str)).asMethod
    val objMirror = m.reflect(im.instance)
    val foo = objMirror.reflectMethod(method)
    println(foo(10))
    foo.asInstanceOf[(Int) => Boolean]
  }

  def main(args: Array[String]): Unit = {
    reflectFoo("foo")
  }
}

Reflect.scala

object Reflect {
  def foo(i: Int): Boolean = i % 2 == 0
}

Output

true
Exception in thread "main" java.lang.ClassCastException: scala.reflect.runtime.JavaMirrors$JavaMirror$JavaVanillaMethodMirror1 cannot be cast to scala.Function1
    at Main$.reflectFoo(Main.scala:12)
    at Main$.main(Main.scala:16)
    at Main.main(Main.scala)





Aucun commentaire:

Enregistrer un commentaire