Scala 2.13 and reflection


#1

I started using scala 2.13.0-M4 for a project and couldn’t find the TypeTag in the reflection library. Also I see that the structure compared to scala 2.12 has changed. What can I do? In particular, I need to get the field names of a generic case class at runtime.

P.S.
The new strawman collection library is great! :smiley:


#2

Was this problem resolved?


#3

Yes, with the Manifest instead, like this:

case class MyClassWrapper[A](name: String)(implicit manifest: Manifest[A]){
    def extractFieldNames[A](implicit m: Manifest[A]): Array[String] = {
        implicitly[Manifest[A]].runtimeClass.getDeclaredFields.map(_.getName)
    }
}

Where A is a generic class


#4

note that Manifest is deprecated, but since you’re only using it to call .runtimeClass, you can (and should) use ClassTag instead

you probably don’t mean for extractFieldNames to have its own A, which shadows the A in the enclosing scope.

nor is it necessary for extractFieldNames to take a manifest, it already has access to the one in the enclosing scope.

so this simplifies to just:

case class MyClassWrapper[A](name: String)(implicit tag: reflect.ClassTag[A]) {
  def fieldNames = tag.runtimeClass.getDeclaredFields.map(_.getName)
}

#5

But one should still be able to find TypeTag, right? import scala.reflect.runtime.universe.TypeTag still seems to work for me.


#6

Thanks, nice solution. I didn’t know where to find the ClassTag! :slight_smile:


#7

Not if you’re using scala 2.13.0-M4 :
08

Or maybe it has been moved…


#8

I don’t think it moved, but maybe there is another gotcha involved.


#9

works fine in 2.13.0-M4 REPL:

Welcome to Scala 2.13.0-M4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.

scala 2.13.0-M4> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag

scala 2.13.0-M4> def foo[T](implicit tag: TypeTag[T]) = tag
foo: [T](implicit tag: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]

scala 2.13.0-M4> foo[String]
res0: reflect.runtime.universe.TypeTag[String] = TypeTag[String]

@alodavi looks like your IDE is confused, or maybe you don’t have the classpath configured correctly to include the 2.13.0-M4 version of scala-reflect.jar?


#10

So it’s definitively my IDE (I’m using Intellij btw). scala.reflect is there, but the subpackage universe is not… I’ll check the classpath configuration


#11

scala.reflect is in the library jar, but scala.reflect.runtime and other subpackages are in scala-reflect.jar. universe is not a package but a val. So you’re missing that jar, as suggested.

There are no instructions about jars (that I could see by skimming). The REPL gets all the tools on its class path by default.


#12

Thanks! This is really helpful!