【问题标题】:Strange behaviour with binding in Groovy based DSL基于 Groovy 的 DSL 中绑定的奇怪行为
【发布时间】:2016-09-23 22:20:48
【问题描述】:

我有一个基于 Groovy 的 DSL,我想从声明的绑定中访问变量。这是我的 DSL 实现:

class Bar {
    String barVal

    void bar(String bar) {
        this.barVal = bar
    }
}

class Foo {
    Bar bar

    void foo(@DelegatesTo(value = Bar, strategy = Closure.DELEGATE_FIRST) closure) {
        def bar = new Bar()
        def code = closure.rehydrate(bar, null, null)
        code()
        this.bar = bar
    }
}

abstract class MyScript extends Script  {

    Foo dslEntryPoint(@DelegatesTo(value = Foo, strategy = Closure.DELEGATE_FIRST) closure) {
        def foo = new Foo()
        def code = closure.rehydrate(foo, null, null)
        code()
        foo
    }
}

下面是我的 DSL 示例以及我如何运行它:

def DSL_NOT_WORKING = """
    dslEntryPoint() {
        foo {
            bar magicValue
        }
    }
"""

def DSL_OK = """
    def myMagicValue = magicValue
    dslEntryPoint() {
        foo {
            bar myMagicValue
        }
    }
"""

CompilerConfiguration config = new CompilerConfiguration(CompilerConfiguration.DEFAULT)
config.scriptBaseClass = MyScript.class.name
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(getClass().getClassLoader(), config)
Class<Script> clazz = groovyClassLoader.parseClass(DSL_NOT_WORKING)
Binding binding = new Binding()
binding.setVariable('magicValue', '42')
Script script = InvokerHelper.createScript(clazz, binding)
Foo foo = script.run() as Foo
assert foo.bar.barVal == '42'

如您所见,当我将变量与def (DSL_OK) 绑定时,我可以在我的 DSL 中访问它的值,否则 (DSL_NOT_WORKING) 我得到一个

java.lang.NullPointerException: Cannot get property 'magicValue' on null object

我做错了什么?如何在没有 def 帮助器声明的情况下访问变量 magicValue?我认为这与在闭包上调用rehydrate 有关,我可以通过this 而不是null,但这似乎不适用于嵌套对象层次结构(Foo->Bar)。

谢谢, 迈克尔

【问题讨论】:

    标签: groovy metaprogramming dsl


    【解决方案1】:

    问题是我使用了rehydrate,它用null 覆盖了所有者和委托。与其在嵌套对象层次结构中记录所有者和委托,不如使用普通委托更简单:

    Foo dslEntryPoint(@DelegatesTo(Foo) closure) {
      Foo foo = new Foo()
      closure.delegate = foo
      closure.call()
      foo
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2020-04-01
      • 1970-01-01
      • 2014-10-12
      相关资源
      最近更新 更多