Ruby 如何将数学运算(如+;,-,*,/)作为参数传递给方法

Ruby 如何将数学运算(如+;,-,*,/)作为参数传递给方法,ruby,Ruby,我正在编写一个反向波兰符号(RPN)计算器,到目前为止,它看起来像这样: class RPNCalculator attr_accessor :numbers, :value def initialize @numbers = [] @value = nil end def push(number) @numbers.push(number) end def plus if value.nil? number1=@numbe

我正在编写一个反向波兰符号(RPN)计算器,到目前为止,它看起来像这样:

class RPNCalculator
  attr_accessor :numbers, :value
  def initialize
    @numbers = []
    @value = nil
  end

  def push(number)
    @numbers.push(number)
  end

  def plus
    if value.nil?
      number1=@numbers.pop
      number2=@numbers.pop
      @value = number1 + number2
    else
      @value += @numbers.pop
    end
  end

  # minus_proc = Proc.new {|a,b| a - b}

  def minus
    number1=@numbers.pop
    number2=@numbers.pop
    @value = number2 - number1
    # operate_on_two_numbers(minus_proc)
  end

  def operate_on_two_numbers(&prc)
    number1=@numbers.pop
    number2=@numbers.pop
    @value = prc.call(number1,number2)
  end

end
例如,以下命令

calculator=RPNCalculator.new
calculator.push(5)
calculator.push(8)
calculator.plus
p calculator.value
产生数字“13”

这就是它应该如何工作的,但是代码中似乎有很多重复。例如,“加”和“减”的功能基本相同;代码中只有“+”和“-”不同

我想尝试定义一个(private)方法,它接受一个对两个数字进行运算的操作作为参数,例如“+”、“-”、“*”或“/”。最好像快捷方式
.inject(:+)
那样使用“快捷方式符号”

我已经尝试了注释掉的行和方法
对两个数字进行操作
,但是当我在行中注释时,我得到了一个错误“未定义的局部变量或方法'minus\u proc'”。

您可以在这里以同样的方式使用任何方法

def operate_on_two_numbers(a, b, op)
  a.send(op, b)
end

operate_on_two_numbers(1, 2, :+)
#=> 3
operate_on_two_numbers(1, 2, :-)
#=> -1
下面是您的完整代码的样子

class RPNCalculator
  attr_accessor :numbers, :value
  def initialize
    @numbers = []
    @value = nil
  end

  def push(number)
    @numbers.push(number)
  end

  def plus
    operate_on_two_numbers(:+)
  end

  def minus
    operate_on_two_numbers(:-)
  end

  private

  def operate_on_two_numbers(op)
    number1=@numbers.pop
    number2=@numbers.pop
    @value = number1.send(op, number2)
  end
end

calculator=RPNCalculator.new
#=> #<RPNCalculator:0x00000002efe460 @numbers=[], @value=nil>
calculator.push(5)
#=> [5]
calculator.push(8)
#=> [5, 8]
calculator.plus
#=> 13
calculator.value
#=> 13
类RPN计算器
属性存取器:数字,:值
def初始化
@数字=[]
@值=零
结束
def推送(数字)
@数字。推送(数字)
结束
def plus
对两个数字进行运算(:+)
结束
减def
操作两个号码(:-)
结束
私有的
def操作两个数字(op)
number1=@numbers.pop
number2=@numbers.pop
@value=number1.send(op,number2)
结束
结束
计算器=RPNCalculator.new
#=> #
计算器推送(5)
#=> [5]
计算器推送(8)
#=> [5, 8]
计算器.plus
#=> 13
计算器值
#=> 13
虽然我最初会接受“.send”方法,但最后我使用了一个接受块作为参数的方法,因为对于除法(“除法”方法),我需要更多的操作(即在除法之前转换为float)。更新后的RPN计算器如下所示

class RPNCalculator
  attr_accessor :numbers, :value
  def initialize
    @numbers = []
    @value = nil
  end

  def push(number)
    @numbers.push(number)
  end

  def plus
    operate_on_two_numbers {|a,b| a + b}
  end

  def minus
    operate_on_two_numbers {|a,b| b - a}
  end

  def times
    operate_on_two_numbers {|a,b| a * b}
  end

  def divide
    operate_on_two_numbers {|a,b| Float(b)/Float(a)}
  end

private

  def operate_on_two_numbers(&prc)
    if @numbers.empty?
      raise "calculator is empty"
    else
      number1=@numbers.pop
      if @value.nil?
        number2=@numbers.pop
        @value = prc.call(number1,number2)
      else
        @value = prc.call(number1,@value)
      end
    end
  end

end

请注意,“加号”、“减号”等现在是单行方法,大部分复杂性已转移到私有的“对两个数字进行运算”方法中。

欢迎使用堆栈溢出。请不要在标题中使用标签,除非它们是句子自然流畅的一部分。因此,使用您设置的标记进行索引,搜索引擎很尊重这些标记。数学运算符已经是方法,所以从某种意义上说,这非常简单。