Groovy DSL: how can I overload any () in Groovy when I create an internal DSL
I am creating an Internal DSL and I would overload any () method from DefaultGroovyMethods.
class RulesProcessor {
}
Any live cell with fewer than two live neighbours dies
The last line is my DSL. I tried propertyMissing, methodMissing, create my Any class, RulesProcessor.metaClass.any, DefaultGroovyMethods.metaClass.any but they don't work.
How can I write code to accept my DSL? Only the first step with the "Any" word gets complicated for me.
source to share
If you can put it in a closure, just delegate it to the object that responds to the method, any
or as in my example invokeMethod
:
class Dsl {
def params = []
def invokeMethod(String method, args) {
params << [method, args]
this
}
def propertyMissing(String prop) { prop }
}
a = {
any live cell with fewer than two live neighbours dies
}
dsl = new Dsl()
a.delegate = dsl
a()
assert dsl.params == [
['any', ['live']],
['cell', ['with']],
['fewer', ['than']],
['two', ['live']],
['neighbours', ['dies']],
]
If you are reading a script from a file, you need a method explicitly called any
:
import org.codehaus.groovy.control.CompilerConfiguration
class Dsl {
def params = []
def invokeMethod(String method, args) {
params << [method, args]
this
}
def any(param) { invokeMethod('any', [param]) }
def propertyMissing(String prop) { prop }
}
code = 'any live cell with fewer than two live neighbours dies'
parsed = new GroovyShell(
getClass().classLoader,
new Binding(),
new CompilerConfiguration(scriptBaseClass : DelegatingScript.class.name)
).parse( code )
dsl = new Dsl()
parsed.setDelegate( dsl )
parsed.run()
assert dsl.params == [
['any', ['live']],
['cell', ['with']],
['fewer', ['than']],
['two', ['live']],
['neighbours', ['dies']],
]
Kudos to mrhaki at CompilerConfiguration.
source to share