Não tenha medo das closures
Você tem medo das closures? Já vi muita gente dizer que closures são perigosas e trazê-las a tona seria como acordar um monstro adormecido (o medonho GOTO – veja uma ótima definição neste link).
Não eu não concordo, closures só querem o seu bem, eis a razão.
Bom, uma closure nada mais é que um trecho de código! Mas o que difere este bloco de instruções chamado closure de um método? A grande diferença neste caso, é que as closures são um pouco mais flexíveis que os métodos, e por sua vez podem até ser passadas como parâmetro na chamada de outras funções, ou seja, podem ser atribuídas a uma variável.
Em java não temos closures nativas na linguagem, e uma das formas de tentar alcançar o objetivo é através do uso de classes anônimas, o que particularmente não me agrada muito, pela sujeira que fica no código.
Em um primeiro exemplo, mais simples, segue como definir uma closure, associá-la a uma variável e depois executá-la. (exemplo em groovy).
def c = {
println "Testando o uso de uma closure"
}
c.call()
Este é um exemplo simples, onde a frase acima será impressa no console.
Para incrementarmos um pouco, podemos fazer com que nossa closure receba um parâmetro para usá-lo dentro da execução, além de criar um método que faça o uso dela. O exemplo abaixo mostra isto.
//definição da closure para dizer oi
def ola = { nome ->
println "E ai ${nome}, tudo bom?"
}
//definição da closure para dizer tchau
def tchau = { nome ->
println "To indo ${nome}, ate a proxima!"
}
//criação do método que fará o uso da closure
void falar(Closure c, String paraQuem) {
c.call(paraQuem)
}
//invoke do método com as closures de parametro
//note que a closure é passada como se fosse uma variável qualquer
falar(ola, "Fulano")
falar(tchau, "Ciclano")
Mas uma das maiores vantagens que eu enxergo nas closures, é a possibilidade de definição delas em runtime. Isso mesmo, conforme você programa, pode criar uma nova closure e chamar uma função que precise dela! Vemos isso em ruby e groovy com frequência para métodos onde iteramos listas e mapas.
Por exemplo, as listas e arrays em groovy possuem um método each que recebe uma closure como parâmetro, esta closure define o que será feito com cada um dos items da lista/array em questão. O exemplo abaixo mostra a praticidade de se fazer a definição da closure inline, ou seja, sem criar uma variável para ela antes.
Em groovy
//groovy
def lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { equipe ->
println "A equipe ${equipe} correu na #F1 em 2009"
}
Em ruby
#ruby
lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { |equipe|
puts "A equipe #{equipe} correu na #F1 em 2009"
}
Em scala
//scala
val teams = List("Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams")
teams foreach {
team => printf("A equipe %s correu na #F1 em 2009", team)
}
Dá pra perceber que a closure foi criada já no momento em que ela foi usada. Desta maneira, além de fácil, um código muito mais limpo e fácil de ser entendido.
Acredite, closures são suas amigas, e estão aqui pra te ajudar, então aproveite!
Ahh, e fica a dica de sempre: Ler a documentação:
Closures em Groovy (wiki) (groovydoc) (definição formal)
Closures (Proc) em Ruby (doc) (wiki)
Closures em Scala (wiki)
Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
Lucas Teixeira
21 Oct 09 at 11:56
Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
lucastex
21 Oct 09 at 11:56
Bacana!!RT @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
Paulo Suzart
21 Oct 09 at 11:58
Bacana!!RT @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
paulosuzart
21 Oct 09 at 11:58
muito bom !!!! RT @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
Humberto Marino
21 Oct 09 at 12:01
[...] This post was mentioned on Twitter by Lucas Teixeira and Paulo Suzart, Humberto Marino. Humberto Marino said: muito bom !!!! RT @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT. [...]
Tweets that mention Não tenha medo das closures at Lucas Teixeira -- Topsy.com
21 Oct 09 at 12:02
O uso closures definitivamente torna o código mais fluente, inteligível e mais prazeroso de trabalhar.
Bacana!
P.S. O exemplo em Scala ficou mais bonito. :P
Paulo Suzart
21 Oct 09 at 12:17
RT: @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa
Emerson Rocco
21 Oct 09 at 12:37
muito bom !!!! RT @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
Humberto Marino
21 Oct 09 at 12:01
RT @lucastex Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa Por favor RT.
Luiz Hespanha
21 Oct 09 at 13:22
RT: @lucastex: Novo post: "Não tenha medo das closures" http://bit.ly/jjmVa
Emerson Bernardino
21 Oct 09 at 12:37
[...] 5: Esta será a nossa tag root do xml: results. A closure que se abre definirá os filhos deste [...]
Renderizando um XML como resposta em grails at Lucas Teixeira
3 Nov 09 at 11:09
[...] Possuía uma lista de objetos (pogos) com várias propriedades, e a partir desta lista, eu precisaria de uma nova lista com apenas os ids de cada um destes objetos, ao invés da clássica iteração para se resgatar os valores, acabei usando o método collect, que recebe uma closure, e para cada objeto da lista, aplica esta closure! [...]
Maravilhas do Groovy: O método ‘collect’ das listas at Lucas Teixeira
6 Nov 09 at 22:28