dilvan
dilvan

Reputation: 2239

Does Groovy's ternary conditional operator have a bug in string expressions?

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

Answers (1)

tim_yates
tim_yates

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

Related Questions