Programming Grails - Cdn.oreilly.com
Programming Grails - Cdn.oreilly.com
Programming Grails - Cdn.oreilly.com
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
}<br />
};<br />
This can be invoked from Groovy just like one created the typical way:<br />
closure(6) // prints "6"<br />
closure(6, 2) // prints "12"<br />
closure(1, 2, 3) // throws a groovy.lang.MissingMethodException<br />
// since there's no 3-param doCall()<br />
Owner, Delegate, and this<br />
this inside a closure is probably not what you expect. Intuitively, it seems like it should<br />
be the closure itself, but it turns out that it’s actually the class instance where the closure<br />
is defined. As such, it’s probably not of much use—the owner and delegate are much<br />
more useful.<br />
The owner of a closure is the surrounding object that contains the closure. It functions<br />
as the target of method invocations inside the closure, and if the method isn’t defined,<br />
then a MissingMethodException will be thrown. In this example, if we create a new<br />
class instance and call the callClosure method (new SomeClass().callClosure()),<br />
it will print Woof!, because the dogAndCat closure calls the existing woof method, but<br />
it will then fail on the meow call because it doesn’t exist:<br />
class SomeClass {<br />
}<br />
void callClosure() {<br />
}<br />
def dogAndCat = {<br />
woof()<br />
meow()<br />
}<br />
dogAndCat()<br />
void woof() {<br />
println "Woof!"<br />
}<br />
You can assign a delegate for a closure to handle method calls. By default, the delegate<br />
is the owner, but you can change it with the setDelegate method. This is frequently<br />
used when parsing DSLs. The DSL can be implemented as a closure, and inner method<br />
calls and property access can be routed to a helper (i.e., the DSL builder), which im‐<br />
plements the logic required when a method or property is called that’s not locally defined<br />
but is valid in the DSL.<br />
One example is the mapping block in <strong>Grails</strong> domain classes. This is a static closure that,<br />
if defined, will be used to customize how the class and fields map to the database:<br />
12 | Chapter 1: Introduction to Groovy