我正在努力做this lesson,我显然错过了一些明显的东西!
require "rpn_calculator" describe RPNCalculator do attr_accessor :calculator before do @calculator = RPNCalculator.new end it "adds two numbers" do calculator.push(2) calculator.push(3) calculator.plus calculator.value.should == 5 end ... # extra credit it "evaluates a string" do calculator.evaluate("1 2 3 * +").should == ((2 * 3) + 1) ... end end
除了@numbers之外,一切都在为我的新手工作。从evaluate方法设置@numbers不会影响其他方法中的@numbers,我真的不明白为什么。我已经尝试了所有可以google的内容,包括将@numbers更改为@@数字,但似乎没有任何帮助。我可以只评估evaluate方法中的字符串...但我已经有了一个很好的加法方法,我可以使用!
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
结果是加号返回失败,因为@numbers为空....
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 '
感谢Frank Schmitt我得到了它的工作。显然,人们不会简单地将方法存储在哈希中。
正确的评估方法:
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
答案 0 :(得分:0)
显然,Ruby会在您将这些方法存储在opps哈希中时调用这些方法。要解决此问题,您可以使用此代码的修改版本:
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
此版本