2016-09-23 3 views
1

宣言されたバインディングから変数にアクセスするGroovyベースのDSLがあります。ここに私のDSLの実装です:Groovyベースの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' 

あなたが見ることができるように、私はdefDSL_OK)で変数をバインドするとき、私ができますアクセス私のDSLで、その値は、そうでない場合(DSL_NOT_WORKING)に対し、私は

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

は私が間違って何をやってもらいますか? defヘルパー宣言なしで変数magicValueにアクセスするにはどうすればよいですか?私はnullの代わりにthisを渡すことができるクロージャーにrehydrateを呼び出すことと関係があると思いますが、これはネストされたオブジェクト階層(Foo-> Bar)では機能しません。

おかげで、 マイケル

答えて

0

は問題がnullと、所有者と代理人が上書きされますrehydrateの私の使用しました。所有者の簿記やネストされたオブジェクト階層の代理ではなく、代わりにプレーンデリゲートを使用する方がはるかに簡単です。

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