33

While going through the Rails guide at http://guides.rubyonrails.org/layouts_and_rendering.html#avoiding-double-render-errors , I wrote a test program to test Ruby's && return, and I got this strange behavior:

def test1
  puts 'hello' && return
  puts 'world'
end

def test2
  puts 'hello' and return
  puts 'world'
end

This is the result output:

irb(main):028:0> test1
=> nil
irb(main):029:0> test2
hello
world
=> nil

What accounts for the difference?

Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
Spec
  • 415
  • 1
  • 5
  • 10

1 Answers1

56

Check out the difference between and and &&. In the examples you give the method puts is called without parens around it's arguments and the difference in precedence changes how it is parsed.

In test 1 && has higher precedence than the method call. So what's actually happening is puts('hello' && return). Arguments are always evaluated before the methods they're called with -- so we first evaluate 'hello' && return. Since 'hello' is truthy the boolean does not short circuit and return is evaluated. When return we exit the method without doing anything else: so nothing is ever logged and the second line isn't run.

In test 2 and has a lower precedence than the method call. So what happens is puts('hello') and return. The puts method logs what is passed to it and then returns nil. nil is a falsey value so the and expression short circuits and the return expression is never evaluated. We just move to the second line where puts 'world' is run.

Community
  • 1
  • 1
Jack Noble
  • 2,018
  • 14
  • 12
  • 1
    thank you!! i notice what the problem is ~~ but i cann't see where "&& has higher precedence than the method call." exist in the http://phrogz.net/ProgrammingRuby/language.html#table_18.4, i cann't prove it... – Spec Sep 22 '16 at 04:31
  • 2
    So well explained...I feel that my upvote and saying thanks is not enough for this knowledge-masterpiece you've shared with us. – Polak Jul 16 '20 at 03:54