Will Will - 8 months ago 64
Scala Question

Case class to map in Scala

Does anyone know if there is a nice way I can convert a Scala case class instance, e.g.

case class MyClass(param1: String, param2: String)
val x = MyClass("hello", "world")

Into a mapping of some kind, e.g.

getCCParams(x) returns "param1" -> "hi", "param2" -> "3"

Which works for any case class, not just predefined ones. I've found you can pull the case class name out by writing a method that interrogates the underlying Product class, e.g.

def getCCName(caseobj: Product) = caseobj.productPrefix
getCCName(x) returns "MyClass"

So I'm looking for a similar solution but for the case class fields. I'd imagine a solution might have to use Java reflection, but I'd hate to write something that might break in a future release of Scala if the underlying implementation of case classes changes.

Currently I'm working on a Scala server and defining the protocol and all its messages and exceptions using case classes, as they are such a beautiful, concise construct for this. But I then need to translate them into a Java map to send over the messaging layer for any client implementation to use. My current implementation just defines a translation for each case class separately, but it would be nice to find a generalised solution.


This should work:

def getCCParams(cc: AnyRef) =
  (Map[String, Any]() /: cc.getClass.getDeclaredFields) {(a, f) =>
    a + (f.getName -> f.get(cc))