G$D/Groovy: Basic Closures

by Marc Hedlund

(For an overview of the G$D/Groovy series, see <http://www.oreillynet.com/pub/wlg/5789>.)

Basic closures in Groovy



Closures are data types just like integers or lists, but the "data" they contain is itself a block of code. To define a closure, use curly braces to contain the closure code:




myClosure = { println "Hello, world!" };


Now you can run your closure using the call() method provided by
the href="http://groovy.codehaus.org/apidocs/groovy/lang/Closure.html">groovy.lang.Closure
class:




myClosure.call(); // prints "Hello, world!"


You can also run your closure as if it were a method or keyword:




myClosure(); // prints "Hello, world!"


Inside each closure, Groovy defines a default variable,
it, for one argument passed to the closure. This makes
it very easy to have a single parameter for your closures without
having to explicitly declare it. The it variable works
just like Perl's $_ variable in subroutines:




namePrinter = { println "Hello, ${it}!" };

namePrinter("John"); // prints "Hello, John!"


What if one argument isn't enough? If you want to use more than
one argument in your closure, you can define them on the first
line
of the closure, and end the line with a pipe character
(|), like this:




nameAndAgePrinter = { name, age | println "${name}, age ${age}" };

nameAndAgePrinter("Lisa", 54) // prints "Lisa, age 54"

nameAndAgePrinter("Henry", 27) // prints "Henry, age 27"


So far, we've been defining a closure by giving it a variable name
("nameAndAgePrinter" in the example above). For any method that takes a
closure as an argument, we can use a shortcut to define the
closure directly after the method call. For instance, let's say a
method named respond() takes a closure as an argument,
allowing you to tell the object to "respond" using code you define in
the closure. The respond method might have documentation like
this:




myclass.respond(groovy.lang.Closure closure)


This says that the respond() method takes one argument, a closure.
You could define the closure as we have above:




response = { // response code... };

myobject.respond(response);


Alternatively, we can define the response inline by placing it just
after the method call:




myobject.respond() { // response code... };


When Groovy sees a closure defined in this way, it will pass that
closure as an argument (the last argument, if there is more than one)
to the named method. You'll see that this shortcut is very
useful for writing clear and readable code.



To learn more about using closures, check out Martin Fowler's discussion of them, which is not specific to Groovy but which provides very helpful examples and discussion. (Thanks to Nelson for the pointer!)