mardi 14 juin 2016

Invoke a method on a generic type with scala and reflect package

My question is based on a search that I have made on the following pages (but I am still to new to scala to succeed in what I want to do):

reflection overview

The purpose of my code is to invoke a method from a generic type and not an instance of a known type.

The following demonstrate the idea:

class A {
  def process = {
    (1 to 1000).foreach(x => x + 10)
  }
}

def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]

def perf[T: ru.TypeTag](t: T, sMethodName: String): Any = {
  val m = ru.runtimeMirror(t.getClass.getClassLoader)

  val myType = ru.typeTag[T].tpe

  val mn = myType.declaration(ru.newTermName(sMethodName)).asMethod

  val im = m.reflect(getTypeTag(t))

  val toCall = im.reflectMethod(mn)

  toCall()

}


val a = new A
perf(a, "process")

The code compile perfectly (on a worksheet) but give the following stack at execution:

scala.ScalaReflectionException: expected a member of class TypeTagImpl, you provided method A$A11.A$A11.A.process
    at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$ErrorNotMember(test-log4j.sc:126)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf$1.apply(test-log4j.sc:221)
    at scala.reflect.runtime.JavaMirrors$JavaMirror.ensuringNotFree(test-log4j.sc:210)
    at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf(test-log4j.sc:220)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:257)
    at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(test-log4j.sc:239)
    at #worksheet#.perf(test-log4j.sc:20)
    at #worksheet#.get$$instance$$res0(test-log4j.sc:28)
    at #worksheet#.#worksheet#(test-log4j.sc:138)

Any idea about how to correct this ?

Many thanks to all





Aucun commentaire:

Enregistrer un commentaire