Похоже, что input
это строка.Вы можете упростить метод, используя Object # public_send .
def calc(str)
stack = []
str.split.each do |token|
if token.match?(/\A-?\d+\z/)
stack << token.to_i
else
rec = stack.shift
arg = stack.shift
stack << rec.public_send(token, arg)
end
end
stack
end
str = "2 3 + 6 * 5 / 2 -"
calc(str)
#=> [4]
Регулярное выражение гласит: «соответствует началу строки (\A
), за которым может следовать знак минус (-?
), за которым следуют одна или несколько цифр (\d+
), за которыми следует конец строки (\z
) ".
Вы можете добавить несколько операторов puts
для выполнения расчетов.
def calc(str)
stack = []
str.split.each do |token|
puts "stack=#{stack}, token=#{token}"
puts " an integer?=#{token.match?(/\A-?\d+\z/)}"
if token.match?(/\A-?\d+\z/)
stack << token.to_i
puts " stack after stack << token.to_i=#{stack}"
else
rec = stack.shift
arg = stack.shift
puts " rec=#{rec}, arg=#{arg}, stack=#{stack}"
stack << rec.public_send(token, arg)
puts " stack after stack<<#{rec}.public_send(#{token},#{arg})=#{stack}"
end
end
stack
end
#=> [4]
и печатает следующее.
stack=[], token=2
an integer?=true
stack after stack << token.to_i=[2]
stack=[2], token=3
an integer?=true
stack after stack << token.to_i=[2, 3]
stack=[2, 3], token=+
an integer?=false
rec=2, arg=3, stack=[]
stack after stack << 2.public_send(+, 3)=[5]
stack=[5], token=6
an integer?=true
stack after stack << token.to_i=[5, 6]
stack=[5, 6], token=*
an integer?=false
rec=5, arg=6, stack=[]
stack after stack << 5.public_send(*, 6)=[30]
stack=[30], token=5
an integer?=true
stack after stack << token.to_i=[30, 5]
stack=[30, 5], token=/
an integer?=false
rec=30, arg=5, stack=[]
stack after stack << 30.public_send(/, 5)=[6]
stack=[6], token=2
an integer?=true
stack after stack << token.to_i=[6, 2]
stack=[6, 2], token=-
an integer?=false
rec=6, arg=2, stack=[]
stack after stack << 6.public_send(-, 2)=[4]