jenkins - Groovy 闭包 - 缺少属性
问题描述
在将 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)
如何解决此错误?
解决方案
您会看到此错误,因为firstScore
在您的代码示例中它是一个方法而不是一个闭包。您可以将firstScore
定义从方法更改为闭包,例如
def firstScore = { array ->
return array[0]
}
或者您可以使用将方法转换为闭包的Groovy方法指针运算符。在这种情况下,您必须通过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
最后但并非最不重要。仔细阅读“可扩展管道代码的最佳实践”博客文章。它解释了编写 Jenkins 管道代码的最佳实践。此外,您需要了解这样一个事实,即管道代码在 Groovy CPS 模式下执行,这有很多限制。了解它们将帮助您解决从 Groovy 跳转到管道代码后肯定会遇到的问题。
推荐阅读
- scala - Scala - 如何使具有自定义排序的 SortedSet 包含多个不同的对象,这些对象具有我们排序的相同值?
- azure-language-understanding - 在没有 Bot Framework 的情况下将 LUIS 用于对话机器人
- java - android:从android应用程序拨打多个电话
- reactjs - 如何在反应js中打印多个组件?
- android - 如何使用 gradle 解决所有 google play-services 依赖项?
- java - 具有相同输出的断言失败错误
- css - 菜单选项卡在折叠时会迷失方向
- sql-server - 如何使用 node.js 从 MSSQL 中插入和获取数据
- javascript - 如何使用 Cognito 身份池生成临时凭证来访问 aws 服务?
- angular - 如何从 angular2 中的承诺中显示烤面包机