Home > Back-end >  Why is code after `else` in a multi-line conditional considered valid ruby syntax?
Why is code after `else` in a multi-line conditional considered valid ruby syntax?

Time:01-05

I was surprised to see that (in Ruby 2.7.4) it is possible to add code after the else keyword, as I've never encountered this before. The following code is considered valid by ruby's built-in syntax checker, and runs quite happily:

if false
  puts 'noop'
else puts 'why is this possible'; 'not returned'
  puts 'and not a syntax error?'
  'returned'
end

# # Output
# why is this possible
# and not a syntax error?
# => "returned"

The in-line code after else is interpreted (puts 'why is this possible') , but the result ('not returned') is discarded.

However if I add return to the else line things get really unexpected:

if false
  puts 'noop'
else puts 'why is this possible'; return 'inline returned'
  puts 'this is now not called'
  'not returned'
end

# # Output
# why is this possible
# => "inline returned"

I don't know what this would be called, so I'm unable to google it – I can't find this documented or mentioned anywhere and don't know if it is an intentional language feature (possibly a side-effect of the single-line if/then/else syntax...?).

Can anybody shed any light on why this works, and if there is a valid use-case for it?

CodePudding user response:

It might be more obvious with explicit line breaks. Your first example is equivalent to:

if false
  puts 'noop'
else
  puts 'why is this possible'
  'not returned'
  puts 'and not a syntax error?'
  'returned'
end

The 'not returned' string literal doesn't do anything on its own. What's left are two puts calls and a return value of 'returned'.

Your second example:

if false
  puts 'noop'
else
  puts 'why is this possible'
  return 'inline returned'
  puts 'this is now not called'
  'not returned'
end

Here, the return keyword will exit the enclosing method after the first puts call right-away with a return value of 'inline returned'. Hence, the following puts and the implicit return value of 'not returned' are ignored.

  • Related