I have the need to dynamically create closures which should call other closures within itself.
Here is an example of what I expect the resulting code to do
Closure execute = {
println("First")
Closure second = {
println("Second")
Closure third = {
println("Third")
}.call()
println("Second")
}.call()
println("First")
}
execute.call()
The above results in the following output:
First
Second
Third
Second
First
How can I create the above closure code dynamically given the following list:
List<String> commands = ["First", "Second", "Third"]
Any pointers appreciated.
So, lets make a function which returns a closure
def wrap(String name, Closure cl = null) {
{ ->
println(name)
// If we were passed a closure, then run it and print the name again
if (cl) {
cl()
println(name)
}
}
}
Then, take our list of commands
List<String> commands = ["First", "Second", "Third"]
And store the current closure in a variable
Closure current = null
Then, lets go backwards through the list, creating a new closure, and wrapping the previous one
commands.reverse().each {
current = wrap(it, current)
}
Then we can run the final closure:
current()
And we get the output:
First
Second
Third
Second
First
🎉
In non-jenkins groovy you can use inject instead of the each with a mutating variable:
Closure current = commands.reverse().inject(null) { curr, command ->
wrap(command, curr)
}
But in my experience of answering Jenkins questions, inject
rarely works, so stick with the first way