Scala muitas vezes me surpreende com a elegancia e integridade da linguagem. O que chamo aqui de integridade, é a forma como a linguagem combina vários conceitos de uma forma uniforme.
Uma das features interessantes de Scala é que ela permite ao programador extrair informações de objetos usando pattern matching, por exemplo se você tiver o seguinte tipo chamado Email:
-
case class Email(name: String, domain: String)
Seria possivel testar se um objeto é do tipo Email, e ao mesmo tempo retornar o name e domain com o seguinte código:
-
unknownObject match {
-
case Email(name, domain) =>
-
println(name + " at " + domain)
-
case _ =>
-
println("It’s not an email")
-
}
No caso de unknownObject ser declarado como:
-
val unknownObject = Email("georges", "gbenatti.net")
A saida seria “georges at gbenatti.net”
Já se unknownObject fosse declarado como:
-
val unknownObject: Any = "georges@gbeatti.net"
A saida seria “It’s not an email”
Mas não seria muito legal se fosse possivel fazer essa segunda opção funcionar ? Ai entra a elegância de Scala, você pode definir extractors que permitem que sejam extraidos dados de determinadas estruturas, sejam elas árvores, listas e até mesmo strings.
Um extractor é um objeto Scala que define um método unapply. A responsabilidade do unapply é fazer o matching de um valor e o separar em seus componentes, para o caso acima o extractor poderia ser definido assim:
-
object EmailStr {
-
def unapply(str: String): Option[(String, String)] = {
-
val parts = str split "@"
-
if (parts.length == 2) Some(parts(0), parts(1)) else None
-
}
-
}
Definido esse extractor poderiamos reescrever o match da seguinte forma:
-
unknownObject match {
-
case Email(name, domain) =>
-
println(name + " at " + domain)
-
case EmailStr(name, domain) =>
-
println(name + " at " + domain)
-
case _ =>
-
println("It’s not an email")
-
}
E ele funcionaria tanto com objetos da classe Email quanto com strings no formato name@domain, ou seja, código final do usuário simples e elegante.
Até mais pp pessoal…
Please click here to download the plugin required to make recent comments work!