Programming Grails - Cdn.oreilly.com
Programming Grails - Cdn.oreilly.com
Programming Grails - Cdn.oreilly.com
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
println hello.getClass().superclass.name<br />
The class itself will have a name like ConsoleScript14$_run_closure1. Nested closures<br />
extend this naming convention; for example, if you look in the classes directory of a<br />
<strong>Grails</strong> application, you’ll see names like BuildConfig$_run_closure1_closure2.class,<br />
which are the result of having repositories, dependencies, and plugins closures de‐<br />
fined within the top-level grails.project.dependency.resolution closure.<br />
The dollar sign in the class and filename will look familiar if you’ve used anonymous<br />
inner classes before. In fact, that’s how they’re implemented. They’re different from<br />
anonymous inner classes in that they can access nonfinal variables outside of their scope.<br />
This is the “close” part of closure—they enclose their scope, making all of the variables<br />
in the scope the closure is in available inside the closure. This can be emulated by an<br />
inner class by using a final variable with mutable state, although it’s cumbersome. For<br />
example, this Java code doesn’t <strong>com</strong>pile, because i isn’t final, and making it final defeats<br />
the purpose, because it needs to be changed inside the onClick method:<br />
interface Clickable {<br />
void onClick()<br />
}<br />
int i = 0;<br />
Clickable c = new Clickable() {<br />
public void onClick() {<br />
System.out.println("i: " + i);<br />
i++;<br />
}<br />
};<br />
We can fix it with a final 1-element array (because the array values are still mutable):<br />
final int[] i = { 0 };<br />
Clickable c = new Clickable() {<br />
public void onClick() {<br />
System.out.println("i: " + i[0]);<br />
i[0]++;<br />
}<br />
};<br />
but it’s an unnatural coding approach. The Groovy equivalent with a closure is a lot<br />
cleaner:<br />
int i = 0<br />
def c = { -><br />
println "i: $i"<br />
i++<br />
} as Clickable<br />
So how does Groovy break this JVM rule that anonymous inner classes can’t access<br />
nonfinal variables? It doesn’t—it uses a trick like the one above. Instead of using arrays<br />
like the above example, there’s a holder class, groovy.lang.Reference. Enclosed vari‐<br />
10 | Chapter 1: Introduction to Groovy