5

This version of the method is defined successfully

def foo(bar)
  baz >= baz(bar)
end

whereas this version of the method has a syntax error:

def foo(bar)
  baz >= baz bar
end

# syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('

Does Ruby think I mean baz(>= baz bar) (which shouldn't work because you can't start an expression with a binary operator?) or (baz >= baz) bar? (which doesn't make any sense)?

I would appreciate some kind of explanation or even better a pointer to Ruby doc which explains why this expression is so difficult to parse.

user513951
  • 12,445
  • 7
  • 65
  • 82
  • 2
    Ruby thinks you mean `(baz >= baz) bar` which makes perfect sense because that's what you wrote. Where as the initial implementation is acting on the return result from `baz(bar)`. While `ruby` and other languages allow you to forgo the parenthesis in some cases `Boolean` operations are not one of them. – engineersmnky Aug 13 '14 at 20:37
  • Thanks @sawa, you eradicated my heat-of-the-moment tone well there. But I still think there was some value in the `irb` prompts, lest someone think I made this story up :) –  Aug 14 '14 at 02:02
  • @engineersmnky I agree with your interpretation, and if I were programming in my usual languages I'd be with you on that. My surprise comes from the fact that Ruby allows you to omit them, and I assumed this was because they had developed some solution to the ambiguity that is typically resolved by making method parens mandatory in a language. My assumption was bolstered (I thought) by the fact that the the documentation http://ruby-doc.org/core-2.1.2/doc/syntax/precedence_rdoc.html doesn't even list method parens in the operator precedence list. –  Aug 14 '14 at 02:32
  • In any case, it appears I need to develop some kind of coding style to avoid these errors in the future. Thanks everyone. –  Aug 14 '14 at 02:32
  • 1
    possible duplicate of [Ruby on Rails - Ruby Operator Precedence - Parentheses](http://stackoverflow.com/questions/17720115/ruby-on-rails-ruby-operator-precedence-parentheses) –  Aug 14 '14 at 02:33

2 Answers2

1

It appears that Ruby has trouble doing comparisons with function calls when not using a parentheses to pass an argument. I've tested this a bit and it seems to be pretty across the board:

irb(main):031:0> 4 < rand 5

#=>SyntaxError: (irb):31: syntax error, unexpected tINTEGER, expecting keyword_do or '{' or '('

Brennan
  • 5,632
  • 2
  • 17
  • 24
0

I think when you this

2.1.2 :013 > def foo(bar)
2.1.2 :014?>   baz >= baz bar
2.1.2 :015?> end

The ruby interpreter thinks you're trying to do this

2.1.2 :013 > def foo(bar)
2.1.2 :014?>   baz(>= baz(bar))
2.1.2 :015?> end

I think that's why a syntax error is occurring. It's always good practice to use parentheses for methods.

Sean Kwon
  • 907
  • 6
  • 12