Ruby operator precedence table
Asked Answered
S

2

54

Show me a definitive, peer-reviewed/maintained Ruby precedence table (of operators, non-operators, and modifiers).

Over the years I have had to rely on the following sources for this information:

1. http://phrogz.net/programmingruby/language.html#table_18.4 - The Pickaxe book, which documents Ruby 1.6, which was released in September 2000, and includes a formatting error or typo ({ is listed as an assignment operator).

2. http://www.techotopia.com/index.php/Ruby_Operator_Precedence - A near copy of the above Pickaxe table, including the erroneous {, and accidentally describes || as Logical 'AND'.

3. http://www.tutorialspoint.com/ruby/ruby_operators.htm - Also a near copy of the Pickaxe table, though it fixes the description of || to Logical 'OR', yet it still lists { as an assignment operator. As well, it lists :: and incorrectly describes it as a constant resolution operator (:: is not an operator).

4. http://my.safaribooksonline.com/book/web-development/ruby/9780596516178/expressions-and-operators/operators - The Ruby Programming Language book, which documents Ruby 1.8 and 1.9, which were released in August 2003 and December 2007, respectively. This book was published in 2008 by David Flanagan and Yukihiro Matsumoto (aka "Matz", the inventor of Ruby). It seems to be the most up-to-date and accurate list of operators, non-operators, modifiers, and supporting information. Incidentally, around 2005, interest in Ruby surged in tandem with Rails, which was released in July 2004.

5. http://romhack.wikia.com/wiki/Ruby_operators - Also documents operators in Ruby 1.9, and includes non-operators and modifiers in its table.

Ruby 2.0 was released in February 2013, and was intended to be fully backward compatible with Ruby 1.9.3. Of the few known incompatibilities, none are related to operators.

Ruby 2.1.0 was released on Christmas Day in 2013, and similarly, no operator incompatibilities are listed.

Thus, I decided to include an answer, based on the Flanagan/Matz book, and made it a community wiki.

Sharpe answered 11/1, 2014 at 8:30 Comment(2)
There's ruby-doc.org/core/doc/syntax/precedence_rdoc.htmlYea
That link is broken. Presumably the same thing is this now: docs.ruby-lang.org/en/master/syntax/precedence_rdoc.htmlRauch
S
69

Ruby 2.1.0, 2.0, 1.9, 1.8

An operator is a token that represents an operation (such as addition or comparison) to be performed on one or more operands. The operands are expressions, and operators allow us to combine these operand expressions into larger expressions. (Ref)

N = arity = The number of operands the operator operates on. (Ref)

A = associativity = The order of evaluation when the same operator (or operators with the same precedence) appear sequentially in an expression. The value L means that expressions are evaluated from left to right. The value R means that expressions are evaluated from right to left. And the value N means that the operator is nonassociative and cannot be used multiple times in an expression without parentheses to specify the evaluation order. (Ref)

M = definability = Ruby implements a number of its operators as methods, allowing classes to define new meanings for those operators. Column M of specifies which operators are methods. Operators marked with a Y are implemented with methods and may be redefined, and operators marked with an N may not. (Ref)

The following table is ordered according to descending precedence (highest precedence at the top).

N A M  Operator(s)            Description
- - -  -----------            -----------
1 R Y  ! ~ +                  boolean NOT, bitwise complement, unary plus
                              (unary plus may be redefined from Ruby 1.9 with +@)

2 R Y  **                     exponentiation
1 R Y  -                      unary minus (redefine with -@)

2 L Y  * / %                  multiplication, division, modulo (remainder)
2 L Y  + -                    addition (or concatenation), subtraction

2 L Y  << >>                  bitwise shift-left (or append), bitwise shift-right
2 L Y  &                      bitwise AND

2 L Y  | ^                    bitwise OR, bitwise XOR (exclusive OR)
2 L Y  < <= >= >              ordering

2 N Y  == === != =~ !~ <=>    equality, pattern matching, comparison
                              (!= and !~ may not be redefined prior to Ruby 1.9)

2 L N  &&                     boolean AND
2 L N  ||                     boolean OR

2 N N  .. ...                 range creation (inclusive and exclusive)
                              and boolean flip-flops

3 R N  ? :                    ternary if-then-else (conditional)
2 L N  rescue                 exception-handling modifier

2 R N  =                      assignment
2 R N  **= *= /= %= += -=     assignment
2 R N  <<= >>=                assignment
2 R N  &&= &= ||= |= ^=       assignment

1 N N  defined?               test variable definition and type
1 R N  not                    boolean NOT (low precedence)
2 L N  and or                 boolean AND, boolean OR (low precedence)
2 N N  if unless while until  conditional and loop modifiers
Sharpe answered 11/1, 2014 at 8:30 Comment(13)
Nice question and answer! I assume these are listed in order of precedence from highest to lowest?Impermanent
Also, is '[]' missing or is it not technically an operator?Impermanent
Thanks. I added a note stating that highest precedence is at the top. I am not sure if [] makes sense for this table, but if someone can justify it then they are welcome to add it. [] can be used for numerous things, so the context would have to be mentioned in the description.Sharpe
The to_proc-operator (unary '&') operator seems to be missing from the table.Ligan
I'd also like to know about method calls, ..Jehiah
This table is partially wrong! The correct order of precedence is if, = and finally rescue. This snippet proofs that rescuehas the lowest precedence. In fact the initial expression (without parenthesis) produces the same results as result2, and not result1 as the table in this answer would suggest.Asthenia
@Asthenia Do you happen to still have that snippet? The Ideone link now points to a blank snippet.Anabantid
The splat operator (unary *) is missing as well. I know it has a lower precedence than multiplication (binary *) though, as call(*[a] * 3) is the same as call(a, a, a)...Mansoor
What about array <<?Letreece
What about method calls with parentheses, what about method calls without? What about {} blocks? What about do end blocks?Lascivious
There is something special about assigning. The 1 == a = 2 evals = and then == that is opposite to this table. See https://mcmap.net/q/162243/-understanding-precedence-of-assignment-and-logical-operator-in-ruby/322020Letreece
Also see https://mcmap.net/q/162244/-ruby-amp-amp-and-operators-misudnerstanding/322020 but that also does not really answer how does it decide to break the operator precedence and are there more cases of the breaking in Ruby.Letreece
Method calls are higher than unary minus – as long as they apply to a variable rather than a literal. -1.in?(-2...-1) #=> false, but v=1; -v.in?(-2...-1) #=! NoMethodError: undefined method `-@' for false:FalseClassMansoor
D
0

RE Ruby Operators Precedence

A useful list can also be found at the bottom of this page:

https://www.tutorialspoint.com/ruby/ruby_operators.htm

RE: Using {}

Local variables begin with a lowercase letter or _. The scope of a local variable ranges from class, module, def, or do to the corresponding end or from a block's opening brace to its close brace {}.

When an uninitialized local variable is referenced, it is interpreted as a call to a method that has no arguments.

Assignment to uninitialized local variables also serves as variable declaration. The variables start to exist until the end of the current scope is reached. The lifetime of local variables is determined when Ruby parses the program.

In the above example, local variables are id, name and addr.

ALSO: You can substitute the value of any Ruby expression into a string using the sequence #{ expr }. Here, expr could be any ruby expression.

Source: https://www.tutorialspoint.com/ruby/ruby_variables.htm

Derwent answered 6/4, 2018 at 19:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.