views:

79

answers:

4

Here's an unexpected find. Something of a very basic Ruby issue that I haven't happened to run into before:

a = "a"

if a
  test = "yes" if a == "a" else "no"
else
  test = "no"
end

Running this yields the error:

syntax error, unexpected kELSE, expecting kEND

Looks like the nested oneliner spills out into the enclosing if statement. What's the generalized solution for this? Not using a oneliner inside an exploded if statement? (It works when exploding the enclosed conditional because it is terminated by an end keyword.

BTW, This is a minimized contrived example, so no need to explain its stupidity or question why I'd do this. I'm looking for a general explanation of how to prevent ruby oneliner if statements from spilling into enclosing conditional scopes.

+2  A: 
test = "yes" if a == "a" else "no"

does not work because the language does not allow it, try

test = a == "a" ? "yes" : "no"
hellvinz
+5  A: 

If you want to put if else into one line, use then like this:

if a then b else c end

and, if you want, you can use ; instead of then, like this:

if a ; b else c end

Also, sometimes you can use this instead of ?::

a && b || c
Nakilon
A: 

The reason for the error is that you are using an 'if modifier' in this line:

test = "yes" if a == "a" else "no"

if modifiers only accept one condition - therefore the syntax error, unexpected kELSE, expecting kEND

As mentioned by others, ternary operators are ideal for these one-liners.

Brian
I suspect the syntax error arises from the outer `if` seeing two `else` in a row.
glenn jackman
Possibly, but you get the same error if you terminate the inner if with an end...
Brian
A: 

Rather than duplicate the "no" answer in both your outer if and else blocks, I'd rewrite the whole thing:

a = "a"
test = if a && a == "a"
         "yes"
       else
         "no"
       end

Or as a one-liner:

a = "a"
test = (a && a == "a") ? "yes" : "no"
Sarah Vessels