I'm new to the reflection API.
I'd like to get a reference to an object from its name. I've made it to the point where I can get a reference using the class name of the object.
$ scala
Welcome to Scala version 2.11.7 ...
scala> case object Foo { val x = 5 }
defined object Foo
scala> import scala.reflect.runtime.{universe => ru}
import scala.reflect.runtime.{universe=>ru}
scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror...
scala> val f = m.reflectModule(m.staticModule(Foo.getClass.getName)).instance.asInstanceOf[Foo.type]
f: Foo.type = Foo
scala> f.x
res0: Int = 5
Works just fine. However, trying to use the computed type name as a string doesn't work:
scala> m.staticModule(Foo.getClass.getName)
res2: reflect.runtime.universe.ModuleSymbol = object iw$Foo$
scala> Foo.getClass.getName
res1: String = Foo$
scala> m.staticModule("Foo$")
scala.ScalaReflectionException: object Foo$ not found.
at scala.reflect.internal.Mirrors$RootsBase.staticModule(Mirrors.scala:162)
at scala.reflect.internal.Mirrors$RootsBase.staticModule(Mirrors.scala:22)
... 33 elided
What am I missing here? Thanks.
This problem appears in REPL only. Try the following in REPL:
scala> Foo.getClass.getName.length
res5: Int = 25
So, the 'Foo$' is not the full name of class Foo
scala> new String(Foo.getClass.getName.getBytes("UTF-8").map(b => if(b==36) '?'.toByte else b), "UTF-8")
res6: String = ?line3.?read??iw??iw?Foo?
And you can call with no problem:
scala>m.staticModule("$line3.$read$$iw$$iw$Foo$")
res7: reflect.runtime.universe.ModuleSymbol = object iw$Foo$
See also: https://issues.scala-lang.org/browse/SI-9335
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With