Reading — step 1 of 5
Learn
~1 min readClosures and Builders
Groovy closures have three contexts for resolving names:
owner— the enclosing scope (where the closure was defined)delegate— a configurable target (default: same as owner)this— the enclosing class
This is what makes Gradle's task { ... } style work — the closure's delegate is set to the task being configured, so methods like dependsOn resolve against it.
class Person {
String name
int age
}
def configure(closure) {
def p = new Person()
closure.delegate = p
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.call()
return p
}
def ada = configure {
name = "Ada" // sets p.name (delegate-first)
age = 36
}
println ada.name // "Ada"
Resolve strategies:
Closure.OWNER_FIRST(default) — owner scope winsClosure.DELEGATE_FIRST— delegate winsClosure.OWNER_ONLY/DELEGATE_ONLY
Pattern: builders. A builder method takes a closure, sets its delegate, and runs it:
def html(@DelegatesTo(HtmlBuilder) Closure body) {
new HtmlBuilder().with(body)
}
html {
title "Hello"
body {
p "World"
}
}
Gradle, MarkupBuilder, JsonBuilder all use this pattern.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…