Groovy DSL:在闭包中设置属性

时间:2012-05-24 17:29:08

标签: groovy map dsl ternary-operator

我想在我的DSL中为规则实现'active'标志。以下是我希望它的样子:

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编译器是否将其视为不完整的三元运算符?

2 个答案:

答案 0 :(得分: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变量中检索送货规则。

免责声明:我现在无法测试我的代码,因此代码中可能会出现一些拼写错误,但您会得到一般的想法:使用基类为您提供规则和属性脚本。

答案 1 :(得分:0)

我在Google+上提出了类似的问题,请参阅here 摘要是:您只能在构造函数(ctors)和函数参数上使用map语法。

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