在将jenkins管道编写为脚本之前,尝试学习groovy闭包。
下面的代码:
def scores = [72,29,32,44,56]
def analyse(closure){
closure(scores)
}
def firstScore(array){
return array[0]
}
analyse(firstScore)
给出错误:
groovy.lang.MissingPropertyException: No such property: firstScore for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
如何解决此错误?
答案 0 :(得分:1)
您看到此错误,因为在您的代码示例中,firstScore
是方法而不是闭包。您可以将firstScore
的定义从方法更改为闭包,例如
def firstScore = { array ->
return array[0]
}
或者您可以使用Groovy的method pointer operator将方法转换为闭包。在这种情况下,您将必须通过以下方式调用analyze
方法:
analyze(this.&firstScore)
除此之外,您的Groovy脚本仍将失败。您尝试在scores
方法内访问analyze
。您需要知道,脚本中定义的任何方法都会自动提升为类级别的方法(每个Groovy脚本都编译为扩展groovy.lang.Script
类的类)。您在Groovy脚本主体中定义的所有其他表达式和语句都是Script.run()
方法的一部分,它们在本地范围内。因此,当方法Script.analyze()
被调用时,它将抱怨不存在的属性scores
,因为scores
在Script.run()
方法的本地范围内。要解决此问题,您可以使用scores
注释对@groovy.transform.Field
进行注释,该注释会将局部变量转换为类级别的属性-在这种情况下,scores
可以从任何方法访问。
下面您可以找到策划脚本的示例:
import groovy.transform.Field
@Field
def scores = [72,29,32,44,56]
def analyse(closure){
closure(scores)
}
def firstScore(array){
return array[0]
}
println analyse(this.&firstScore)
输出:
72
最后但并非最不重要的一点。仔细阅读"Best Practices for Scalable Pipeline Code"博客文章。它解释了编写Jenkins管道代码的最佳实践。另外,您需要意识到以下事实:流水线代码在has a bunch of limitations的Groovy CPS模式下执行。了解它们将帮助您解决从Groovy跳转到管道代码后肯定会遇到的问题。