以下のJenkinsパイプラインスクリプトを実行すると:
def some_var = "some value"
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
pipeline {
agent any
stages {
stage ("Run") {
steps {
pr()
}
}
}
}
私はこのエラーを受け取ります:
groovy.lang.MissingPropertyException: No such property: some_var for class: groovy.lang.Binding
def
がsome_var
から削除されている場合、正常に機能します。誰かがこの動作を引き起こすスコープ規則について説明できますか?
def
は、メインスクリプト本体で他のメソッドからアクセスできません。def
は、異なるスクリプトからでも任意の方法で直接アクセスできます。それは悪い習慣です。def
and_@Field
_ 注釈は、同じスクリプトで定義されたメソッドから直接アクセスできます。Groovyがそのスクリプトをコンパイルすると、実際にはroughlyのようなクラスにすべてを移動します
_class Script1 {
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
def run() {
def some_var = "some value"
pipeline {
agent any
stages {
stage ("Run") {
steps {
pr()
}
}
}
}
}
}
_
_some_var
_は、別のメソッドのローカル変数であるため、明らかにpr()
の範囲外です。
変数を定義するときwithoutdef
は、実際にその変数をスクリプトの Binding に入れます(so -calledbinding variables)。したがって、groovyはpr()
メソッドを最初に実行するときに、_some_var
_という名前のローカル変数を見つけようとし、存在しない場合は、Binding(そのために存在するため) def
なしで定義した)。
Jenkinsはすべてのスクリプトで同じバインディングを共有するため、複数のスクリプト(load
ステップ)をロードすると、これらのすべてのスクリプトでバインディング変数にアクセスできるため、バインディング変数は悪い習慣と見なされます。より良い代替手段は _@Field
_ アノテーションを使用することです。これにより、1つのスクリプト内のすべてのメソッドで変数にアクセスできるようになり、他のスクリプトに公開されることはありません。
_import groovy.transform.Field
@Field
def some_var = "some value"
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
//your pipeline
_
Groovyがこのスクリプトをクラスにコンパイルすると、次のようになります。
_class Script1 {
def some_var = "some value"
def pr() {
def another_var = "another " + some_var
echo "${another_var}"
}
def run() {
//your pipeline
}
}
_