首页 文章

Groovy DSL:在闭包中设置属性

提问于
浏览
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
  }
}

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

这个语法实际上做了什么?它看起来像一个 Map 分配,但没有 . 或者groovy编译器将其视为不完整的三元运算符?

2 回答

  • 4

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

    Edited, it is not clear in you example if you have more than one shipping instance. In my second try, I assume that the answer is yes

    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变量中检索出货规则 .

    disclaimer: 我现在无法测试我的代码,因此代码中可能存在一些拼写错误,但您可以获得一般的想法:使用基类来为脚本提供规则和属性 .

  • 0

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

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

相关问题