Extractors con un argumento o ninguno.
Si un unapply método extrae un solo valor este debe retornar un Optional por ejemplo:
object Number {
def unapply(input: String): Option[Int] =
try {
Some(input.trim.toInt)
} catch {
case ex: NumberFormatException => None
}
}
Con este extractor podemos extraer el numero de un string :
val Number(n) = "1729"
Un extractor puede chequear un valor en este caso debe retornar un booleano:
object IsCompound {
def unapply(input: String) = input.contains(" ")
}
Se puede utilizar un extractor para agregar un test en una expresión
pattern matching:
author match {
case Name(first, IsCompound()) => …
case Name(first, last) => …
}
El método unapplySeq
Si utilizamos el extract en una secuencia, estaremos llamando a unapplySeq que retorna Option[Seq[A]] , donde A es el valor extraído:
object Name {
def unapplySeq(input: String): Option[Seq[String]] =
if (input.trim == "") None else Some(input.trim.split("\\s+"))
}
Dado este método ahora podemos utilizar un conjunto de parámetros:
author match {
case Name(first, last) => …
case Name(first, middle, last) => …
case Name(first, “van”, “der”, last) => ...
}
Ojo, no se puede tener un método unapply y un unapplySeq con similar parámetros.
Invocación dinámica
Scala es un lenguaje de tipado estático y fuertemente tipado. Es decir que informa los errores de tipo en momento de compilación.
Si un tipo extiende de el trait scala.Dynamic, entonces el método llamadas, getters y setters se reescriben como llamadas a métodos especiales que pueden inspeccionar el nombre de la llamada original y los parámetros, y luego tomar acciones arbitrarias.
Veamos algunos ejemplos. Supongamos que la persona es una instancia de un tipo que se extiende
de Dynamic. Una declaración:
person.lastName = "Doe"
se puede remplazar:
person.updateDynamic ("lastName") ("Doe")
La clase Person debe tener dicho método:
clase Persona {
...
def updateDynamic (campo: String) (newValue: String) {...}
}
Depende de nosotros si implementamos el método updateDynamic.
Otro ejemplo:
val name = person.lastName
puede ser remplazado por:
val name = name.selectDynamic("lastName")
El metodo selectDynamic debe retornar un valor simple.
En scala existe DynamicProps que extiende a Dynamic y sobre escribe sus métodos:
class DynamicProps(val props: java.util.Properties) extends Dynamic {
def updateDynamic(name: String)(value: String) {
props.setProperty(name.replaceAll("_", "."), value)
}
def selectDynamic(name: String) =
props.getProperty(name.replaceAll("_", "."))
}
}