Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1
Chapter 5

[ 89 ]

Groovy has special handling for methods whose last parameter is a closure. When
invoking these methods, the closure can be defined anonymously after the method
call parentheses. So, yet another legitimate way to call the preceding line is:


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

The general convention is not to use parentheses unless there are parameters in
addition to the closure:


given:
def flintstones = ["Fred", "Barney", "Wilma"]
when: "we call findIndexOf passing int and a Closure"
def result = flintstones.findIndexOf(0) { it == 'Wilma'}
then:
result == 2

The signature of the GDK findIndexOf method is:


int findIndexOf(int, Closure)

We can define our own methods that accept closures as parameters. The simplest
case is a method that accepts only a single closure as a parameter:


def closureMethod(Closure c) {
c.call()
}

when: "we invoke a method that accepts a closure"
closureMethod {
println "Closure called"
}
then: "the Closure passed in was executed"
"Closure called" == output()

Method parameters as DSL


Method parameters as DSL is an extremely useful construct when we want to wrap a
closure in some other code. Suppose we have some locking and unlocking that needs
to occur around the execution of a closure. Rather than the writer of the code locking
via a locking API call, we can implement the locking within a locker method that
accepts the closure:


def locked(Closure c) {
callToLockingMethod()
c.call()
callToUnLockingMethod()
}
Free download pdf