Reputation: 1105
I am having trouble nesting multiple Closures in Groovy. Nesting only one works like a charm:
def nestedClosure = { Closure cl -> doSomething { cl() } }
But how can I programatically nest multiple closures from e.g. a list of Closures?
Suppose this example:
Closure main = { println "Hello world" }
Closure consumer1 = { x -> println("1"); x(); println("1 END") }
Closure consumer2 = { x -> println("2"); x(); println("2 END") }
Closure consumer3 = { x -> println("3"); x(); println("3 END") }
I want to somehow chain and nest these consumers to get the output of:
1
2
3
Hello world
3 END
2 END
1 END
Tried currying, insane loops and googling for quite a while now, but can't seem to get any working idea.
Upvotes: 2
Views: 273
Reputation: 1105
The trick was to curry the last Closure with the deepest nested "main" Closure and consecutively currying the remaining Closures and overwriting main:
def main = { println "Hallo" }
Closure consumer1 = { x -> println("1"); x(); println("1 END") }
Closure consumer2 = { x -> println("2"); x(); println("2 END") }
Closure consumer3 = { x -> println("3"); x(); println("3 END") }
def consumers = [consumer1, consumer2, consumer3]
// Nest main in last closure
consumers.reverse().each {
main = it.curry(main)
}
main()
Notce: since I internally used Consumer<Closure>
to remain argument safety, I needed to curry Consumer.accept
via Method pointer:
def main = { println "Hallo" }
Consumer<Closure> consumer1 = { x -> println("1"); x(); println("1 END") }
Consumer<Closure> consumer2 = { x -> println("2"); x(); println("2 END") }
Consumer<Closure> consumer3 = { x -> println("3"); x(); println("3 END") }
def consumers = [consumer1, consumer2, consumer3]
consumers.reverse().each {
main = it.&accept.curry(main)
}
main()
Upvotes: 3