Reputation: 2180
http://phrogz.net/programmingruby/language.html#table_18.4 The table provided by the link above only gives the precedence of ruby's operators. What's the precedence of a method(or should I say: a message/ function) ?
For example, when I input something as below in irb
Math.sqrt 2 + 2
I got 2.0 as the result. Without the definite rules of the precedence, I just can't decide where to use the parens and where to omit them. So, someone please help me get rid of this uncertainty. Thanks in advance!
Upvotes: 5
Views: 1889
Reputation: 20857
We can use your Programming Ruby link as a starting point and discover for ourselves where unparenthesized method-calls belong in the precedence table. I'm only going to show the final tests that pinpoint the location.
It's lower than defined?
:
defined? Math.sqrt 2
# => SyntaxError: unexpected tINTEGER, expecting end-of-input
Aha, it's higher than not
:
not Math.sqrt 2
=> false
Now you know exactly when you should use parentheses.
Sidenote
(thanks to Martin Demello's link to ruby-talk for reminding me)
Keep in mind that the operators in the table only apply when not being used in the method-call syntax. Example - the following doesn't obey the rules for *
and +
because they're not being used as operators, but methods:
# This happens because unparenthesized method calls are right-associative.
2.* 5.+ 2 # => 14
If that looks confusing, the same thing is happening here:
# The `modulo` is evaluated first because it's on the right
Math.sqrt 9.modulo 5
Upvotes: 2
Reputation:
Any operator has precedence over the method call.
It is highly recommended to use ()
for method calls to avoid situations like the one you're asking about.
Upvotes: 4
Reputation: 33732
In Ruby any operator has precedence over method calls, e.g. operators are evaluated first.
However the example Math.sqrt 2 + 2
is a good illustration on how hard to read and unintuitive it can be to leave out parentheses. One might expect Math.sqrt(2) + 2
to be evaluated here.
When you come across a line like this, you might think: What did the coder intend? Is this a bug?
It is always a good idea to use parentheses whenever you can, to make clear what you want, especially when there is a method call or multiple operators - it's just good style, and the lowest risk approach (e.g. don't make assumptions, but make yourself clear by using parentheses).
It never hurts to add extra parentheses in expressions, but leaving them out can hurt quite a bit.
Here's a nice example which I recently came across:
def foo(arg)
raise "error"
end
x = foo 4 rescue 7
x
=> nil # oops!
x = foo(4) rescue 7
x
=> 7
I hope this nicely illustrates why it's important to use parentheses
Also:
Check here, under "Calling a Method" : http://ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html Quote:
[...] If there is no ambiguity you can omit the parentheses around the argument list when calling a method.[...] However, except in the simplest cases we don't recommend this---there are some subtle problems that can trip you up.[In particular, you must use parentheses on a method call that is itself a parameter to another method call (unless it is the last parameter).] Our rule is simple: if there's any doubt, use parentheses.
See also: http://phrogz.net/programmingruby/language.html
Upvotes: 1
Reputation: 12336
Ruby method invocation has a lower precedence than any of the operators, but that's not the full story - there are some edge cases that are nonobvious. Your question got me curious about one of them, so I asked on the ruby-talk mailing list. You should find the resulting thread helpful.
Also, read this blog post for a good argument that you should use parentheses liberally, especially while you are learning ruby.
Upvotes: 2