Search code examples
scalaobjectreflectionmembers

How can I get all (non-final) object vals and subobject vals using reflection in Scala?


Note: This question is not a duplicate of How can I get all object vals and subobject vals using reflection in Scala?

The answer provided in that question only works for final members.

For example:

scala> object Settings {
     |   val Host = "host"
     | }
defined module Settings

deepMembers(Settings)
res0: Map[String,String] = Map()

Solution

  • It must be a duplicate, but I need a refresher:

    $ scala
    Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> object Settings { val Host = "host" ; val Guest = "guest" }
    defined object Settings
    
    scala> import reflect.runtime._,universe._
    import reflect.runtime._
    import universe._
    
    scala> val im = currentMirror reflect Settings
    im: reflect.runtime.universe.InstanceMirror = instance mirror for Settings$@c8e4bb0
    
    scala> im.symbol.asClass.typeSignature.members filter (s => s.isTerm && s.asTerm.isAccessor)
    res0: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value Guest, value Host)
    
    scala> res0 map (im reflectMethod _.asMethod) map (_.apply())
    res2: Iterable[Any] = List(guest, host)