04.07.2013 Views

Programming Grails - Cdn.oreilly.com

Programming Grails - Cdn.oreilly.com

Programming Grails - Cdn.oreilly.com

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!