Need4Steed
Need4Steed

Reputation: 2180

What's the precedence of ruby's method call

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

Answers (4)

Kelvin
Kelvin

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

user979912
user979912

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

Tilo
Tilo

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

Martin DeMello
Martin DeMello

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

Related Questions