Groovy DSL:当我创建内部DSL时,如何在Groovy中重载any()

时间:2014-10-07 13:17:32

标签: groovy dsl

我创建内部DSL,我会从DefaultGroovyMethods重载any()方法。

class RulesProcessor {

}

Any live cell with fewer than two live neighbours dies

最后一行是我的DSL。我尝试了propertyMissing,methodMissing,创建了我的Any类,RulesProcessor.metaClass.any,DefaultGroovyMethods.metaClass.any,但是它们没有用。

如何编写代码来接受我的DSL?只有第一步与任何'这句话对我来说很复杂。

1 个答案:

答案 0 :(得分:2)

如果你可以将它放在一个闭包中,只需将它委托给一个响应any方法的对象,或者如我的例子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']],
]

如果您正在从文件中读取脚本,则显示需要明确调用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']],
]

在CompilerConfiguration上感谢mrhaki