Using ruby, I can overload the operators in my functions. I wonder if I can overload the precedence somehow (cheats are allowed). For example:
class Odd
attr_accessor :value
def initialize(value)
@value = value
end
def +(odd)
Odd.new(@value - odd.value)
end
def *(odd)
Odd.new(@value / odd.value)
end
end
a = Odd.new(5)
b = Odd.new(5)
c = Odd.new(5)
puts (a + b * c).value
This script prints 4
thanks to the precedence. How can I make it print 0
by evaluating first the sum then the multiplication?
I don't think you can do this without hacking Ruby itself; of course, doing this would probably break a non-trivial amount of all the other Ruby code you're using. You see, Ruby doesn't know what a
, b
, or c
are when it is figuring out what
a + b * c
means, it only knows the built-in precedence of the +
and *
operators and how to translate those operators to method calls.
You could manually convert the operators to method calls and manually order them according to your preferred precedence:
a.+(b).*(c).value
but that's pretty nasty (less nasty than confusing everyone by changing the precedence of operators though).
An alternative would be to put "a + b * c"
into a string and then write your own parser for that string. This would just be a fancy way of dynamically building a.+(b).*(c)
though.
Then there's the obvious: use parentheses and leave the precedence alone:
((a + b) * c).value
Keep the full stack until it is evaluated at last.
class Odd
attr_reader :stack
def initialize *stack; @stack = stack end
def + other; Odd.new(*(stack + [:-] + other.stack)) end
def * other; Odd.new(*(stack + [:/] + other.stack)) end
def value
while i = stack.index(:-) do stack[i - 1, 3] = stack[i - 1] - stack[i + 1] end
while i = stack.index(:/) do stack[i - 1, 3] = stack[i - 1] / stack[i + 1] end
stack.first
end
end
a = Odd.new(5)
b = Odd.new(5)
c = Odd.new(5)
puts (a + b * c).value
# => 0
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.