Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1
Chapter 1

[ 17 ]

In Groovy markup, this XML can be generated simply with the following
code fragment:


def builder = new groovy.xml.MarkupBuilder()
builder.book {
author 'Fergal Dearle'
title 'Groovy for DSL'
}

At first glance, this looks like strange special case syntax for markup. It's not! The
structure of this code can be explained through the use of closures and the optional
syntax that we've discussed in this chapter. We will go into this in great detail in
Chapter 5, Groovy Closures, but it is interesting at this point to see how the clever
use of some language features can yield a powerful DSL-like markup syntax.


Breaking down the preceding code a little, we can rewrite it as:


def builder = new groovy.xml.MarkupBuilder()
def closure = {
author 'Fergal Dearle'
title 'Groovy for DSL'
}
// pass a closure to book method
builder.book( closure)
// which can be written without parentheses
builder.book closure
// or just inline the closure as a parameter
builder.book {
...
}

In other words, the code between the curly braces is in fact a closure, which is passed
to the book method of MarkupBuilder. Parentheses being optional, we can simply
declare the closure inline after the method name, which gives the neat effect of
seeming to mirror the markup structure that we expect in the output.


Similarly, author and title are just method invocations on MarkupBuilder with
the optional parentheses missing. Extending this paradigm a little further, we can
decide to have author take a closure parameter as well:


def builder = new groovy.xml.MarkupBuilder()
builder.book {
author {
Free download pdf