Groovy脚本上下文和方法解析

时间:2015-05-04 18:34:19

标签: groovy

我遇到以下Groovy脚本/

的问题
nestedView("JS Pipelines") {
  views {
    build_pipelines.each {
      def build_pipeline = it
      buildPipelineView(build_pipeline.build_name + " JS Pipeline") {
        selectedJob(build_pipeline.start_job)
      }
    }
  }
}

根据buildPipelineView的内容,需要多次调用views方法,该方法位于build_pipelines对象(code)上。

当在buildPipelineView调用中包含对{}的调用时,该方法将解析为在更高的上下文中定义的另一个buildPipelineView方法。删除每个块后,方法调用将正确解析。 buildPipelineView如何在每次通话中正确解决?

3 个答案:

答案 0 :(得分:1)

如果有疑问,请存储外部引用,该引用对于闭包是可见的,并在该对象上显式调用此方法:

nestedView("JS Pipelines") {
  views {
    final outer = it
    build_pipelines.each { build_pipeline ->
      outer.buildPipelineView(build_pipeline.build_name + " JS Pipeline") {
        selectedJob(build_pipeline.start_job)
      }
    }
  }
}

答案 1 :(得分:1)

其实ContextHelper.groovyjob-dsl-plugin已经改变了views闭包的委托策略,正是views的方括号。

在你的例子中,只有 build_pipelines 被包裹在 views 闭包中,所以你确实改变了 each 闭包的委托策略,但是 buildPipelineView 闭包仍然保持默认策略.

您可以使用 getDelegate 将委托策略返回给 buildPipelineView 闭包。

nestedView("JS Pipelines") {
  views {
    build_pipelines.each {
      def build_pipeline = it
      def d = getDelegate()
      d.buildPipelineView(build_pipeline.build_name + " JS Pipeline") {
        selectedJob(build_pipeline.start_job)
      }
    }
  }
}

答案 2 :(得分:0)

在嵌套闭包中,每个闭包都有一个owner,它立即包含闭包。 (请参阅Groovy文档中的Delegation strategy。)对于传递给each的闭包,其owner是传递给views的闭包。

Groovy闭包的默认delegation strategyClosure.OWNER_FIRST,这意味着当您访问属性或调用方法而未明确提及接收器[如buildPipelineView(...)]时,Groovy将尝试访问owner上的属性/方法,如果没有,它将访问委托上的属性/方法。

直接的解决方案是明确地提供接收器,例如this.buildPipelineView(...)