簡體   English   中英

Groovy在Groovy閉包中使用DSL評估字符串

[英]Groovy evaluate Strings using DSL while in a Groovy closure

這類似於從字符串生成Closure的Need Groovy語法幫助,但稍微復雜一點:

我正在使用不受控制的復雜DSL(特別是Jenkins Job DSL,但是為了清楚起見,我使用的是假設的DSL),並且我將代碼分解為返回的閉包。 這段代碼中所有不以“ my”開頭的閉包都是假設的DSL:

//scriptContext is a reference to the original script as this is a util class
static def myMethod(def scriptContext) {
    //everything here comes from some hypothetical DSL
    scriptContext.diningTable() {
        ....
        fruits myCreateFruitsClosure()
        ....
    }
}    
static def myCreateFruitsClosure() {
   return {
       apple('Gala') {
           seed("brown")
           shape {
              funky()
              dimpled()
           }
       }
   }
}

以上工作正常。

現在讓我們說,我希望動態指定蘋果的詳細信息,並從某個地方(例如XML)加載一些常規代碼。

我現在有:

// I pass in the script context for the binding
static def myCreateFruitsClosure(def scriptContext) {
   return {
       apple('Gala') {
           // This comes from somewhere in real life:
           def code = """seed("blue"); shape { oval() ; cardioid() }"""
           def evalWrapper = new GroovyShell(context.binding).evaluate(' { -> ' + code + '}')                      
           evalWrapper()
       }
   }
}

而且,我得到“方法沒有簽名:Script1.seed()”顯然,由於不使用eval,因此seed()方法確實存在,因為它以前可以工作,所以我的上下文/范圍是錯誤的。

我試過了:

  • Eval.me()和Script.evaluate()的各種組合
  • 創建方法並將其運行到外部並運行評價()
  • 要將“ createFruitsClosure()”的內容直接移動到“ myMethod()”中

所有這些都會產生略有不同的錯誤。 正確的方法是什么?

最終, 通過以下方式獲得了這項工作

  1. 切換到打開的代碼塊而不是閉包
  2. 在動態代碼中使用對“所有者”的顯式引用,並通過Binding使其可用。 在此示例中,所有者的“自我”是蘋果封口。

結果如下:

static def myCreateFruitsClosure() {
    return {
        apple {
            def code = """
                L:{
                   self.seed("blue")
                   self.shape {
                       oval()
                       cardioid()
                   }
                }"""  
            // sometimes "self: delegate" is appropriate instead of this:
            new GroovyShell(new Binding([self: owner])).evaluate(code)
        }
    }
}

我想這比我嘗試做的要簡單。 請注意“ L:”以強制valuate()將代碼視為開放代碼塊而不是閉包。

如果有人有更好的方法,請告訴我,但這行之有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM