scala reflection scala-2.10 case-class

Reflexión de Scala 2.10, ¿cómo extraigo los valores de campo de una clase de caso



reflection scala-2.10 (2)

Si quieres ser más elegante, puedes ordenarlos inspeccionando el símbolo del constructor. Este código funciona incluso si el tipo de clase de caso en cuestión tiene múltiples constructores definidos.

import scala.collection.immutable.ListMap import scala.reflect.runtime.universe._ /** * Returns a map from formal parameter names to types, containing one * mapping for each constructor argument. The resulting map (a ListMap) * preserves the order of the primary constructor''s parameter list. */ def caseClassParamsOf[T: TypeTag]: ListMap[String, Type] = { val tpe = typeOf[T] val constructorSymbol = tpe.decl(termNames.CONSTRUCTOR) val defaultConstructor = if (constructorSymbol.isMethod) constructorSymbol.asMethod else { val ctors = constructorSymbol.asTerm.alternatives ctors.map(_.asMethod).find(_.isPrimaryConstructor).get } ListMap[String, Type]() ++ defaultConstructor.paramLists.reduceLeft(_ ++ _).map { sym => sym.name.toString -> tpe.member(sym.name).asMethod.returnType } }

¿Cómo puedo extraer los valores de campo de una clase de caso en scala usando el nuevo modelo de reflexión en scala 2.10? Por ejemplo, el uso de lo siguiente no elimina los métodos de campo

def getMethods[T:TypeTag](t:T) = typeOf[T].members.collect { case m:MethodSymbol => m }

Planeo bombearlos a

for {field <- fields} { currentMirror.reflect(caseClass).reflectField(field).get }


MethodSymbol tiene un método isCaseAccessor que le permite hacer precisamente esto:

def getMethods[T: TypeTag] = typeOf[T].members.collect { case m: MethodSymbol if m.isCaseAccessor => m }.toList

Ahora puedes escribir lo siguiente:

scala> case class Person(name: String, age: Int) defined class Person scala> getMethods[Person] res1: List[reflect.runtime.universe.MethodSymbol] = List(value age, value name)

Y obtienes solo los símbolos de método que deseas.