4

This is essentially my question, but the accepted answer stops at returning their symbols rather than the case objects themselves.

In theory, this should be easy:

def getCaseObjects(enumType: Type) = {
    val m = ru.runtimeMirror(getClass.getClassLoader)
    enumType.typeSymbol.asClass.knownDirectSubclasses map { subclass =>
        val enumObjMirror = m.reflectClass(subclass.asClass.toType.typeSymbol.asClass)
        enumObjMirror.reflectConstructor(subclass.asClass.toType.decl(ru.termNames.CONSTRUCTOR).asMethod)()
    }
}

And this works!

...Except that they are entirely new instances compared to the ones contained in their Parent sealed trait; hooray, I've busted the "case objects are singleton" assumption!

I could override equals and hashCode in my Parent sealed trait and be done with it, but I'd prefer a way to get those particular case objects rather than ones that happen to look like them. Is this possible? I'm on 2.11 if that makes any difference.

Community
  • 1
  • 1
helgridly
  • 133
  • 8

1 Answers1

3

Assuming you use the sealedDescendants method in the post you reference, I believe you should be able to get the underlying objects like:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{ universe => ru }
val m = ru.runtimeMirror(getClass.getClassLoader)

val descendants = sealedDescendants[Parent] getOrElse Set.empty

val objects = descendants.map({ desc =>
  val mod = m.staticModule(desc.asClass.name.decoded)
  m.reflectModule(mod).instance
})
Brian Kent
  • 3,754
  • 1
  • 26
  • 31