0

Here is what I have:

sealed abstract class Codes(list: List[String])
object UVWCodes extends Codes(List("U", "V", "W"))
object XYZCodes extends Codes(List("X", "Y", "Z"))

I would like to use macros to expand the listed values into:

parse(str: String): Codes = str match {
  case "U" | "V" | "W" => UVWCodes
  case "X" | "Y" | "Z" => XYZCodes
}

Since Codes is a sealed class, it's possible to get the list of its subclasses. However, how to extract the list of code literals ("U", "V", etc)?

pgrandjean
  • 676
  • 1
  • 9
  • 19

2 Answers2

1

When you write

sealed abstract class Codes(list: List[String])

list is just a constructor argument which is lost if not used. If you prefix with the keyword val it becomes an immutable property so you can access outside

sealed abstract class Codes(val list: List[String])

UVWCodes.list // Valid code
Edmondo
  • 19,559
  • 13
  • 62
  • 115
1

With decisive contributions from @Edmondo1984 and snippets from elsewhere, here's a fully coded solution:

import scala.reflect.runtime.universe._

sealed abstract class Codes(val list: List[String])
object UVWCodes extends Codes(List("U", "V", "W"))
object XYZCodes extends Codes(List("X", "Y", "Z"))


object FindObjectsByReflection {
  def main(args: Array[String]) = {
    val c = typeOf[Codes].typeSymbol.asClass.knownDirectSubclasses
    c.foreach { x =>
      val d = getObjectInstance(x.fullName).asInstanceOf[Codes]
      println(d.list)
    }
  }
  def getObjectInstance(clsName: String): AnyRef = {
    val mirror = runtimeMirror(getClass.getClassLoader)
    val module = mirror.staticModule(clsName)
    mirror.reflectModule(module).instance.asInstanceOf[AnyRef]
  }

}
radumanolescu
  • 4,059
  • 2
  • 31
  • 44