2

我想在我的 DSL 中为规则实现一个“活动”标志。这是我希望它的样子:

Shipping("Standard") {
    active: true
    description: "some text"

    rules {
      ... define rules here
    }
}

以下是我按照几个教程让一切运行的方法:

Script dslScript = new GroovyShell().parse(new File("Standard"))

dslScript.metaClass.Shipping = { String name, Closure cl ->
  ShippingDelegate delegate = new ShippingDelegate()
  delegate.name = name
  cl.delegate = delegate
  cl.setResolveStrategy Closure.DELEGATE_FIRST
  cl()
}

dslScript.run()

ShippingDelegate 很简单:

class ShippingDelegate {

  String name

  void rules(Closure cl) {
    ... do stuff here
  }
}

这一切都运行良好,没有投诉,但我怎样才能访问“活动”或“描述”?

无论如何,这种语法实际上做了什么?它看起来像一个地图分配,但没有。还是 groovy 编译器将其视为不完整的三元运算符?

4

2 回答 2

4

我可以建议对您的 DSL 进行一些小改动,以便简化您的设计吗?

已编辑,在您的示例中不清楚您是否有多个运输实例。在我的第二次尝试中,我认为答案是肯定的

class ShippingRules {
    boolean active
    String description
    String name


    ShippingRules(String name) {
        this.name=name
    }

    def rules(Closure c) {
        c.delegate=this
        c()
    }
}



abstract class ShippingRulesScript extends Script {
    def shipppingRules =[]

    def shipping(String name, Closure c) {
        def newRules=new ShippingRules(name)
        shipppingRules << newRules
        c.delegate=newRules
        c()
    }
}

def cfg= new CompilerConfiguration(
    scriptBaseClass:ShippingRulesScript.name
)
Script dslScript = new GroovyShell(cfg).parse(new File("Standard"))

dslScript.run()

DSL应该改成这样:

shipping("Standard") {
    active= true
    description= "some text"

    rules {
      ... define rules here
    }
}
shipping("International") {
    active= true
    description= "some text"

    rules {
      ... define rules here
    }
}

即失去运输的资本,并使用分配而不是冒号。

然后,您稍后可以从 dslScript shippingRules 变量中检索运输规则。

免责声明:我现在无法测试我的代码,因此代码中可能有一些拼写错误,但您明白了:使用一个基类,您可以在其中为脚本提供规则和属性。

于 2012-05-25T20:59:08.023 回答
0

我在 Google+ 上问过类似的问题,请参见此处
总结是:您只能在构造函数(ctors)和函数参数上使用映射语法。

有趣的是它不会抛出异常。

于 2013-05-02T09:58:59.180 回答