Reputation: 2239
Groovy's ternary condition operator has a very strange behavior in this code:
def f = true
println 'a' + f?'b':'z' + 'c' // b
f = false
println 'a' + f?'b':'z' + 'c' // b
It prints b in both cases and ignores the other two strings without warning! Is that a bug in the Groovy compiler?
If numbers are used, in the place of strings, an error is generated:
def f = true
println 1 + f?2:3 + 3 // Error: Cannot find matching method int#plus(boolean).
Parenthesis fix the problem:
def f = true
println 'a' + (f?'b':'z') + 'c' // abc
println 1 + (f?2:3) + 3 // 6
Can someone explain this behavior?
Upvotes: 2
Views: 1191
Reputation: 171084
It's all to do with operator precedence.
Most* languages have a rule of precedence for operators (which ones are taken first when there are multiple options). Groovys order can be found here.
As you can see, +
comes in at position 5, but ternary comes in at a lowly 14
This mean that Groovy parses your expression as (added brackets to show):
('a' + f) ? 'b' : ('z' + 'c')
Which when you fill in the variables, becomes
('atrue') ? 'b' : ('zc')
In groovy, any non empty (and non null) String is considered true
when taken as a boolean, so the result of the above is b
As you've seen, the answer is to add parentheses to show the parser what you actually want
(* Lisps, Forth and probably more don't 😉)
Upvotes: 4