Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Groovy Closures


[ 86 ]

What is a closure?


Closures are such an unfamiliar concept to begin with that it can be hard to grasp
initially. Closures have characteristics that make them look like a method in so far
as we can pass parameters to them and they can return a value. However, unlike
methods, closures are anonymous. A closure is just a snippet of code that can be
assigned to a variable and executed later:


def flintstones = ["Fred","Barney"]
def greeter = { println "Hello, ${it}" }
flintstones.each( greeter )
greeter "Wilma"
greeter = { }
flintstones.each( greeter )
greeter "Wilma"

Because closures are anonymous, they can easily be lost or overwritten. In the
preceding example, we defined a variable greeter to contain a closure that prints a
greeting. After greeter is overwritten with an empty closure, any reference to the
original closure is lost.


It's important to remember that greeter is not the closure. It is a variable
that contains a closure, so it can be supplanted at any time.

Given that greeter is a variable with dynamic type, we could have assigned any
other object to it. All closures are a subclass of the type groovy.lang.Closure. As
groovy.lang is automatically imported, we can refer to Closure as a type within
our code. By declaring our closures explicitly as Closure, we cannot accidentally
assign a non-closure to them:


Closure greeter = { println it }

For each closure that is declared in our code, Groovy generates a
Closure class for us, which is a subclass of groovy.lang.Closure.
Our closure object is an instance of this class. Although we cannot predict
which exact type of closure is generated, we can rely on it being a subtype
of groovy.lang.Closure.

http://www.ebook3000.com
Free download pdf