0

Ruby's operators, like + or *, follow the order of precedence as in mathematics when used in the syntax-sugar form. In the following, * is called before +:

# Syntax-sugar form
5 + 5 * 2 # => 15

In the non-syntax-sugar form, the methods follow the linear order in which they are written. In the following, + is called before *:

# Non-syntax-sugar form
5.+(5).*(2) # => 20

Methods that I define, like the + method as follows, work both with and without the syntax-sugar form:

class WackyInt
  attr_reader :value     

  def initialize(value)
    @value = value
  end

  def +(other)
    WackyInt.new(value + other.value)
  end
end

ONE = WackyInt.new 1
FIVE = WackyInt.new 5

# As operators
ONE + FIVE # => #<WackyInt @number=-4>
# As methods
ONE.+(FIVE) # => #<WackyInt @number=-4>

The defined operators follow the respective order of precedence both in the syntax-sugar form and the non-syntax-sugar form.

How can Ruby parse this?

sawa
  • 165,429
  • 45
  • 277
  • 381
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
  • `#`, not `#` – Tom Lord Apr 17 '18 at 13:41
  • I guess the operators are recognized by Ruby's parser which turns them into method calls (according to their precedence). Whether the receiver is a literal, a variable, a method call or a constant doesn't really matter. – Stefan Apr 17 '18 at 13:42
  • 1
    I'm not sure what you're asking, exactly -- *"How is Ruby able to parse this?"* Are you asking how does a parser work? Are you asking where _exactly_ in the parser is responsible for interpreting `+` operations? Are you surprised by ruby's behaviour here; is there something about it you don't understand? – Tom Lord Apr 17 '18 at 13:47
  • I feel brackets are influencing the behaviour. Try define also * as method in WacyInt class. Then: `# As operators p FIVE + TWO * FIVE # => @value=15 p 5 + 2 * 5 # => 15 # As methods p FIVE.+(TWO).*(FIVE) # => @value=35 p 5.+(2).*(5) # => 35 # As methods no brackets p FIVE.+TWO.*FIVE # => # @value=15 p 5.+2.*5 # => 15` Something [like this](https://stackoverflow.com/a/48159938/5239030) – iGian Apr 17 '18 at 13:52
  • The MRI parser is over 11,000 lines of code... [here](https://github.com/ruby/ruby/blob/8cd5ccdc7fc38d271ebe33c63d64f2950a97aea0/parse.y#L7937-L7945) is a relevant section in relation to handling the `+` character. Does that answer your question?! – Tom Lord Apr 17 '18 at 13:55
  • _'So, I know that Ruby's operators – like almost all other programming languages – follow the order of operations'_. I know what you mean, but I don't think it's clear what you're talking about here. Needs clarification. – Sagar Pandya Apr 17 '18 at 14:21
  • You need to also define `*` and show order or precedence in complex cases in order to show your point with overwritten methods. – sawa Apr 18 '18 at 05:20

1 Answers1

0

Tokenizing, parsing, and assigning computational precedence is separated from calling and executing the methods. What you can overwrite is what is done when a method is called. That does not change how a Ruby code is tokeninzed or parsed, and hence computational precedence is not affected by that.

sawa
  • 165,429
  • 45
  • 277
  • 381