Ruby Testfirst.org-rpn_calculator-如何在方法之间传递变量?

Ruby Testfirst.org-rpn_calculator-如何在方法之间传递变量?,ruby,rpn,test-first,Ruby,Rpn,Test First,我正在努力去做,很明显我错过了一些显而易见的事情! 需要“rpn_计算器” 描述RPN计算器do 属性存取器:计算器 在做之前 @计算器=RPNCalculator.new 结束 它“添加两个数字”可以吗 计算器推送(2) 计算器推送(3) 计算器.plus calculator.value.should==5 结束 ... #额外学分 它“计算字符串”do 计算器。评估(“1 2 3*+”)。应该== ((2 * 3) + 1) ... 结束 结束 在我的新手眼里,除了@数字之外,一切

我正在努力去做,很明显我错过了一些显而易见的事情!

需要“rpn_计算器” 描述RPN计算器do 属性存取器:计算器 在做之前 @计算器=RPNCalculator.new 结束 它“添加两个数字”可以吗 计算器推送(2) 计算器推送(3) 计算器.plus calculator.value.should==5 结束 ... #额外学分 它“计算字符串”do 计算器。评估(“1 2 3*+”)。应该== ((2 * 3) + 1) ... 结束 结束

在我的新手眼里,除了@数字之外,一切都很正常。在evaluate方法中设置@numbers不会影响其他方法中的@numbers,我真的不明白为什么。我已经在谷歌上尝试了一切,包括将@numbers改为@numbers,但似乎没有任何帮助。我可以在evaluate方法中计算字符串。。。但我已经有了一个很好的加号方法,我可以使用!

类RPN计算器 属性存取器:数字 def初始化 @数字=[] 结束 def推送(n) @数字。推送(n) 结束 def plus @数字。长度>1@numbers.push(@numbers.pop(2).reduce(:+):失败 结束 减def @数字。长度>1@numbers.push(@numbers.pop(2).reduce(:-):失败 结束 def分配 @数字。长度>1@push(@numbers.pop(2).injection{| x,y | x.to_f/y}):失败 结束 def时间 @数字。长度>1@numbers.push(@numbers.pop(2).reduce(:*):失败 结束 def值 @值=@number[-1] 结束 def代币(pol) pol.split(“”).map{n|n.to|i.to|s==n?n.to|i:n.to|sym} 结束 def评估(pol) 订单=[] opps={:+=>正,:-=>负,:/=>除,:*=>倍} tokens(pol).reverse.chunk{n|n.is|a?(Integer)}.each{e,a | e==true?a.reverse.each{a | push(a)}:a.each{a | order.push(a)} order.reverse.each{| o |(opps[o])} 结束 def故障 开始 引发异常。新建(“计算器为空”) 结束 结束 结束

结果是加号返回失败,因为@numbers为空。。。。

RPN计算器 加两个数字 加三个数字 从第一个数字中减去第二个数字 加减 乘与除 明确地解析运算符优先级 如果没有足够的值堆叠,则会以信息方式失败 标记字符串 计算字符串(失败-1) 失败: 1) RPNCalculator对字符串求值 失败/错误:计算器。评估(“1 2 3*+”)。应== 例外情况: 计算器是空的 #/12_rpn_calculator/rpn_calculator.rb:59:in'fail' #/12_rpn_calculator/rpn_calculator.rb:14:in'plus' #/12_rpn_calculator/rpn_calculator.rb:39:in'evaluate' #./12_rpn_计算器/rpn_计算器\u规范rb:134:in‘块(2级)in’

多亏了你,我才让它工作起来。显然,我们并不是简单地将方法存储在散列中。

正确的评估方法:

def评估(pol) @numbers=[]#因为这会在不清除@numbers的情况下进行4次测试 opps={:+=>Proc.new{plus},:-=>Proc.new{minus},:/=>Proc.new{divide},:*=>Proc.new{times}方法在Proc中,谢谢Frank:D tokens(pol).chunk{n|n.is|a?(整数)}.each{e,a | e==true?a.each{a | push(a)}:a.each{o |(opps[o].call)} @数字[0] 结束

显然,只要将方法存储在opps散列中,Ruby就会调用这些方法。要解决此问题,您可以使用此代码的修改版本:

  def evaluate(pol)
    order = []
    opps = {:+ => Proc.new {plus}, :- => Proc.new{minus}, :/ => Proc.new{divide}, :* => Proc.new{times} }
    tokens(pol).reverse.chunk{|n| n.is_a?(Integer)}.each{|e,a| e == true ? a.reverse.each{|a| push(a) } : a.each {|a| or
der.push(a) }}
    order.reverse.each {|o| (opps[o].call) }
  end
这个版本

  • 将进程存储在opps散列中,该散列只调用您的方法
  • 使用Proc.call实际调用您的方法

老兄,我的大脑左右摇摆不定!非常感谢-这正是问题所在!这可能不是我想要的教训,但这绝对是我今天最大的突破!不客气:-请考虑接受我的回答,如果它解决了你的问题。哎呀,对不起…我才意识到复选标记就是这个意思! class RPNCalculator attr_accessor :numbers def initialize @numbers = [] end def push(n) @numbers.push(n) end def plus @numbers.length > 1 ? @numbers.push(@numbers.pop(2).reduce(:+) ) : fail end def minus @numbers.length > 1 ? @numbers.push(@numbers.pop(2).reduce(:-) ) : fail end def divide @numbers.length > 1 ? @numbers.push(@numbers.pop(2).inject{|x,y| x.to_f / y} ) : fail end def times @numbers.length > 1 ? @numbers.push(@numbers.pop(2).reduce(:*) ) : fail end def value @value = @numbers[-1] end def tokens(pol) pol.split(' ').map{|n| n.to_i.to_s == n ? n.to_i : n.to_sym} end def evaluate(pol) order = [] opps = {:+ => plus, :- => minus, :/ => divide, :* => times } tokens(pol).reverse.chunk{|n| n.is_a?(Integer)}.each{|e,a| e == true ? a.reverse.each{|a| push(a) } : a.each {|a| order.push(a) }} order.reverse.each {|o| (opps[o]) } end def fail begin raise Exception.new("calculator is empty") end end end RPNCalculator adds two numbers adds three numbers subtracts the second number from the first number adds and subtracts multiplies and divides resolves operator precedence unambiguously fails informatively when there's not enough values stacked away tokenizes a string evaluates a string (FAILED - 1) Failures: 1) RPNCalculator evaluates a string Failure/Error: calculator.evaluate("1 2 3 * +").should == Exception: calculator is empty # ./12_rpn_calculator/rpn_calculator.rb:59:in `fail' # ./12_rpn_calculator/rpn_calculator.rb:14:in `plus' # ./12_rpn_calculator/rpn_calculator.rb:39:in `evaluate' # ./12_rpn_calculator/rpn_calculator_spec.rb:134:in `block (2 levels) in ' def evaluate(pol) @numbers = [] # because this does 4 tests without clearing @numbers opps = {:+ => Proc.new {plus}, :- => Proc.new{minus}, :/ => Proc.new{divide}, :* => Proc.new{times} } # method in proc, thank you Frank :D tokens(pol).chunk{|n| n.is_a?(Integer)}.each{|e,a| e == true ? a.each{|a| push(a) } : a.each {|o| (opps[o].call) }} @numbers[0] end
  def evaluate(pol)
    order = []
    opps = {:+ => Proc.new {plus}, :- => Proc.new{minus}, :/ => Proc.new{divide}, :* => Proc.new{times} }
    tokens(pol).reverse.chunk{|n| n.is_a?(Integer)}.each{|e,a| e == true ? a.reverse.each{|a| push(a) } : a.each {|a| or
der.push(a) }}
    order.reverse.each {|o| (opps[o].call) }
  end