Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Groovy Closures


[ 88 ]

The java.lang.Object class has a number of similar methods such as each, find,
every, any, and so on. Because these methods are defined as part of Object, you
can call them on any Groovy or Java object. They make little sense on most objects,
but they do something sensible if not very useful:


given: "an Integer"
def number = 1
when: "we call the each method on it"
number.each { println it }
then: "just the object itself gets passed into the Closure"
"1" == output()

given: "a String"
def string = "String"
when: "we call the each method on the String"
string.each { println it }
then: "each knows to iterate the chars in the String"
"""S
t
r
i
n
g""" == output()

These methods all have specific implementations for all of the collection types,
including arrays, lists, ranges, and maps. So, what is actually happening when we
see the call to flintstones.each is that we are calling the list's implementation of
the each method. Because each takes a Closure object as its last and only parameter,
the following code block is interpreted by Groovy as an anonymous Closure object
to be passed to the method.


The actual call to the closure passed to each is deferred until the body of the each
method itself is called. The closure may be called multiple times—once for every
element in the collection.


Closures as method parameters


We already know that parentheses around method parameters are optional,
so the previous call to each can also be considered equivalent to:


flintstones.each ({ println "Hello, ${it}")

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