【问题标题】:Anybody to explain the magic of groovy closure / Jenkins任何人都可以解释 groovy 闭包的魔力/詹金斯
【发布时间】:2019-05-21 08:40:43
【问题描述】:

我想了解基于 groovy DSL 和闭包的 Jenkins 管道的一部分代码。

我有一个 Jenkins 文件如下:

foo {
  var1 = "foo value 1"
  var2 = "foo value 2"
}

我的 Jenkins 共享库中有一个 groovy 脚本(vars 目录中的 foo.groovy):

def call(body) {
   def config = [:]
   body.resolveStrategy = Closure.DELEGATE_FIRST
   body.delegate = config
   body()

   println config.var1 // display foo value 1 : for me the magic is here !!
}

我想了解 groovy / jenkins 机制,当调用闭包时,map config 设置为变量 var1 和 var2。

我(几乎)了解闭包机制和委托方法,但是我们怎么知道配置映射对闭包的委托字段的影响允许使用我的 Jenkinsfile 中声明的变量构建映射?

我希望我的问题很清楚! :)

问候,

史蒂夫

【问题讨论】:

    标签: jenkins groovy


    【解决方案1】:

    当一个属性在闭包中被引用,并且该引用无法在闭包中解析时,会尝试在不同的“地方”解析它

    1. this
    2. 闭包的delegate 属性,可以重新分配
    3. 关闭的owner

    在您的示例中,var1var2 是无法在闭包中解析的引用示例。

    以下将闭包的委托分配给config,并确保这是用于解析未解析引用的第一个“位置”

    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    

    因此,当我们在闭包中设置属性var1var2 时,它们会针对config 进行解析,即设置为此Map 的键值对。

    如果您的示例更改为:

    foo {
       def var3 = "some value"
    
       var1 = "foo value 1"
       var2 = "foo value 2"
       var3 = "some value"
    }
    

    var3config 解析,因为它可以在闭包中解析。

    更新

    回应您的评论(我认为):为什么将闭包的委托设置为映射会导致将键值对添加到该映射中?

    var1 = "foo value 1" 无法在闭包中解析时,它会根据地图解析,因此

    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    

    所以这实际上意味着我们正在调用

    config.var1 = "foo value 1"
    

    这是 Groovy 的简写

    config.put("var1", "foo value 1")
    

    如果您将代码更改为直接调用put方法可能会更容易理解,例如

    def foo = {
      put('var1', "foo value 1")
    }
    
    def call(body) {
       def config = [:]
       body.resolveStrategy = Closure.DELEGATE_FIRST
       body.delegate = config
       body()
    
       println config.var1 // display foo value 1 : for me the magic is here !!
    }
    
    call(foo)
    

    如果您在 Groovy 控制台中运行此代码,您会看到它还会打印“foo value 1”。

    如果你还在苦苦挣扎,也许this question 会有所帮助。

    【讨论】:

    • 感谢您的回复,但我仍然不明白我是如何知道将地图对象分配给我的闭包的委托字段的,以及在 groovy 中使用声明的字段构造我的地图的机制是什么我的闭包(例如,如果我将一个字符串对象分配给委托字段,我认为这不起作用)?
    猜你喜欢
    • 2019-01-09
    • 2021-09-08
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多