Written on
Groovy Sneak Peak: The DelegatingScript Base Class
As shown by Guillaume Laforge at Gr8Conf 2013 in Copenhagen, Groovy 2.2 will come with a neat feature for writing custom DSL Groovy scripts: theDelegatingScript
base class.
Groovy Scripts FTW
One way to write Groovy code is within so-called "scripts". At runtime, Groovy script code is converted to aScript
[2] descendant class and an instance of that class is created. I nice tool to actually see the generated classes (and even byte-code) is the groovyConsole's AST browser bundled amongst other useful programs with the Groovy distribution.

groovy.lang.Script
.
Changing the Base Class
A nice way to further customize custom Groovy scripts is to set a custom base class. A custom base class can be used to provide "global" methods and variables that might be shared within a group of scripts. For example, let's assume we wanted to write a bunch of Robot DSL scripts, we would create a custom base class containing the DSLs variables and functions. In order to set a custom script base class, we need to create an instance ofCompilerConfiguration
and run the script with that instance.
CompilerConfiguration cc = new CompilerConfiguration();
cc.setScriptBaseClass(DelegatingScript.class);
GroovyShell sh = new GroovyShell(cl, new Binding(), cc);
DelegatingScript script = (DelegatingScript)sh.parse(new File("my.dsl"))
// setting the delegate object here!
script.setDelegate(new RobotDSL());
script.run();
CompilerConfiguration
is created to set Groovy's new DelegatingScript
as the script's base class. And, using DelegatingScript#setDelegate(Object)
the actual delegate object - the object to which all calls are delegated first - is set.
Assuming our RobotDSL class looks like this:
class RobotDSL {
def robot = [:]
def createRobot(Closure c) {
robot = [:]
c.delegate = robot
c.resolveStrategy = Closure.DELEGATE_ONLY
c()
robots << robot
robot
}
def steps(int number) {
new Movement(number)
}
static class Movement {
def moveLeft(int steps) {
// move the robot to the left
}
def moveRight(int steps) {
// move the robot to the right
}
}
// ...
}
createRobot {
name = 'André'
}
steps 4 moveLeft
steps 2 moveRight
DelegatingScript
provides a nice way for DSL scripts to remove all DSL setup code to the outside of the script.
Conclusion
Groovy 2.2 comes with a nice feature to automatically delegate all calls in a script to a dedicated delegate object: theDelegatingScript
base class.