I'm starting to learn grails and there is some groovy syntax that I don't get at all, and is undocumented as far as I can tell because I don't know what it's called.
What are 'grails', 'views', and 'gsp' in the code below?
grails {
views {
gsp {
encoding = 'UTF-8'
// ...
}
}
}
Thanks! p.s. I feel like an idiot for not being able to figure this out...
It is used to separate where you declare bindings for your closure from the actual code, eg: def myClosure = { x, y -> x + y } the part before -> declares that the closure has two arguments named x and y while the second part is the code of the closure.
1.2.A multiline comment starts with /* and can be found at any position in the line. The characters following /* will be considered part of the comment, including new line characters, up to the first */ closing the comment.
This is an example of DSL (domain specific language) code. In Groovy, many DSLs are implemented as Groovy code, although sometimes it can look pretty funky. This code block is run as Groovy code, and it's more clear that it's code if you add in the omitted optional parentheses:
grails({
views({
gsp({
encoding = 'UTF-8'
// ...
})
})
})
and more so if we replace the property set call to the equivalent method call
grails({
views({
gsp({
setEncoding('UTF-8')
// ...
})
})
})
If you ran this in a console or as part of other Groovy code or in a Grails app it would fail, because there's no 'grails' method taking a closure as an argument, or a similar 'views' or 'gsp' method, and there's no setEncoding(String)
method either. But when run as DSL code, often the code is run inside a closure whose delegate
is set to a DSL helper class that handles the resulting methodMissing
and propertyMissing
calls.
This helper looks at the method name and the number and/or types of the method arguments (or property name and value type) and if they are valid for the DSL, it does the corresponding work, otherwise it throws a MissingMethodException
/MissingPropertyException
, or a DSL-specific exception, or handles the problem some other way.
In this case, there's a configuration DSL handler that translates these method calls into config property calls.
There are several other DSLs in use in a Grails app that work the same way. The mapping
and constraints
blocks in domain classes, the grails.project.dependency.resolution
block in BuildConfig.groovy
, etc. All are evaluated as Groovy code, and the missing method/property calls configure GORM mappings, constraint definitions, plugin dependencies, etc.
Programming Groovy 2 is a particularly good Groovy book for learning DSLs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With