What is the difference between defining variables using def and without?

14,314

Solution 1

It's a difference of scope. When you assign a value to a variable without a "def" or other type, in a Groovy script, it's added to the "binding", the global variables for the script. That means it can be accessed from all functions within the script. It's a lot like if you had the variable defined at the top of the script.

You could wind up with unexpected behavior if multiple threads are acting on the script.

def a = {
  x = 1
  println x
}
def b = {
  x = 2
  println x
}
new Thread(a).start()
new Thread(b).start()

... could produce two ones, two twos, or a mix.

In contrast, using "def" makes a local variable:

def a = {
  def x = 1
  println x
}
def b = {
  def x = 2
  println x
}
new Thread(a).start()
new Thread(b).start()

... will always print a 1 and a 2, in arbitrary order.

Solution 2

It's a good question, but it's more a Groovy question.

From what I understand, defining a variable without def keyword will work from a script, but not if you were in a class method. Example from this blog post :

class MyTest {
    def testMethod() {
        y = 3
        println y
    }    
}

t = new MyTest()
t.testMethod()

Variable t will be defined without problem but y definition will throw an exception.

What it means is that in our context (Jenkins pipeline) you could always define your variable without the def keyword because you are always in a script context and your variables will be bound to the script. However, I think it is good practice to use def keyword because it shows you know when you instantiate your variables, and it also can avoid some problems of duplicate variables definitions (if you define them with the def keyword at least compilation will fail if you defined the same variable twice).

Finally, from Groovy documentation :

When using def in Groovy, the actual type holder is Object (so you can assign any object to variables defined with def, and return any kind of object if a method is declared returning def).

So you might want to be specific and specify the type of variable you are defining. In your case you could define cwd as :

String cwd = pwd()

It would forbid you to do things like :

def cwd = pwd()
cwd = 1000     // Valid code

String cwd2 = pwd()
cwd2 = 1000    // Will fail compilation
Share:
14,314
Itai Ganot
Author by

Itai Ganot

Architect and Lecturer in the field of DevOps Engineering. LinkedIn: https://www.linkedin.com/in/itaiganot

Updated on June 04, 2022

Comments

  • Itai Ganot
    Itai Ganot almost 2 years

    In relation to Jenkins DSL, what is the difference between:

    def cwd = pwd()
    

    and

    cwd = pwd()
    

    ?