Reputation: 3017
While trying to reinvent the if/else syntax with closures in groovy, I couldn't manage to make it work. I think putting multiple closures outside the parenthesis is not permitted, but it could be something else.
If it isn't permitted, how would you reproduce the if/else syntax? This is a thought experiment, so don't tell me about the the inefficiency of this implementation.
My code:
void ifx(boolean condition, Closure action){
["${true.toString()}": action].get(condition.toString(), {})()
}
void ifx(boolean condition, Closure action, Closure elsex){
["${true.toString()}": action, "${false.toString()}": elsex].get(condition.toString())()
}
void elsex(Closure action){
action()
}
ifx(1==2){
println("1")
} ifx(1==3){
println("2")
} elsex{
println("3")
}
Error message:
java.lang.NullPointerException: Cannot invoke method ifx() on null object
Upvotes: 0
Views: 1014
Reputation: 14559
Something along these lines works:
updated with closures to avoid global state:
def ifx( outerCondition, outerBlock ) {
boolean matched = false
def realIfx
realIfx = { condition, block ->
if (condition) {
matched = true
block()
}
[ifx: realIfx, elsex: { elseBlock -> if(!matched) elseBlock() }]
}
realIfx outerCondition, outerBlock
}
And some testing:
def result
ifx(1 == 2) {
result = 1
} ifx(1 == 3) {
result = 2
} elsex {
result = 3
}
assert result == 3
result = null
ifx (1 == 2) {
result = 1
} ifx (2 == 2) {
result = 2
} elsex {
result = 3
}
assert result == 2
result = null
ifx (true) {
result = 1
} ifx (2 == 1) {
result = 2
} elsex {
result = 3
}
assert result == 1
Upvotes: 2
Reputation: 6518
ifx (1==2) {} ifx(1==3) {} elsex {}
is a command chain expression translating to ifx(1==2,{}).ifx(1==3,{}).elsex({})
. Since void translates to null, it should be clear that the second ifx call then fails with a NPE. To realize an if/else kind of thing I would maybe do the following
void ifx(boolean condition, Closure ifBlock, Closure elseBlock) {
....
}
ifx (1==2) {...}{...}
meaning not using an else keyword at all. IF you want to keep your idea, you have to return something on which you can call elsex and ifx.. Or if not ifx, then put a newline in after the first ifx
Upvotes: 1