Ruby's one liner "and return"
return, ruby, styles
Solution
To understand oneliners like the one in your question, you need to memorize Ruby operators and their precedence. Or, more precisely, Ruby syntax. You need to see the statements in exactly the same way that Ruby interpreter does. It must become your second nature. Let us now take a look at your one-liner
puts "foo" and return if true
Let us separate the unrelated issues first. Keyword `return` is only applicable inside methods or lambdas and is not really the subject of your question. Furthermore, trailing `if true` is always valid and thus seems unnecessary. To discuss your question in general, let us define method `#bar` and a variable `baz`
def bar
puts "bar"
end
baz = true
and let us talk about a modified one-liner
puts "foo" and bar if baz
If you have memorized Ruby syntax, you will be able parenthesize the line exactly as Ruby sees it:
( puts( "foo" ) and ( bar ) ) if ( baz )
Trailing `if` behaves like an operator with very low priority. Whole line from the beginning up to `if` is executed only if `baz` is truey, which it is. Therefore,
puts "foo" and bar
gets executed. It is parenthesized as follows:
puts( "foo" ) and ( bar )
You can see that `puts "foo"` is executed first, printing `foo` on the screen and returning `nil`. Since `nil` is falsey, operator `and` just returns it and `bar` on its right side never gets executed.
As for
if baz
puts "foo"
bar
end
it is equivalent to:
( puts( "foo" ); bar ) if ( baz )
You can see the difference: `puts "foo"` and `bar` are not joined by `and`, but are independent logical lines. The return value of the first line is discarded and does not affect execution of the second line.
Finally, let us look at what happens upon replacing `and` with `&&`. Because `&&` operator has much higher priority than `and`, oneliner
puts "foo" && bar
becomes
puts( "foo" && bar )
In other words, value of `"foo" && bar` would be computed first, and then passed as an argument to `#puts` method. Because string `"foo"` is considered truey, execution proceeds to `bar`, which prints `"bar"` on the screen and returns `nil`. You can try by yourself that the value of
"foo" && bar
is `nil`, with `"bar"` printed on the screen as a side effect.
puts( "foo" && bar )
thus becomes
puts( nil )
which causes an empty line to be printed on the screen.
The morale is that that one should learn the syntax. Ruby designer made a big step of making the code readable at a glance like a book.
Problem
I recently discovered a Ruby gotcha which I don't completely understand. So, can someone explain to me why these 2 following statements in Ruby are not the same- ``` puts "foo" and return if true ``` VS ``` if true puts "foo" return end ```