【问题标题】:Nil when calling a method on the variable, but not nil when calling just the variable调用变量上的方法时为零,但仅调用变量时不为零
【发布时间】:2014-06-08 18:42:19
【问题描述】:

不明白为什么@nums.pop 在 value 方法中不起作用。它似乎告诉我它不能为 nil 做到这一点,但如果我只是说@nums,它表明数组中确实有一些东西。那为什么我不能弹出呢?

class RPNCalculator


    def initialize
        @value = value
        nums ||= []
        @nums = nums
    end


    def push(num)
        @nums << num
    end

    def plus
        if @nums[-2] == nil || @nums[-1] == nil
            raise "calculator is empty"
        else
            @value = @nums.pop + @nums.pop
            @nums.push(@value)
        end

    end

    def minus
        if @nums[-2] == nil || @nums[-1] == nil
            raise "calculator is empty"
        else
        @value = @nums[-2] - @nums[-1]
        @nums.pop(2)
        @nums.push(@value)
        end
    end

    def divide
        if @nums[-2] == nil || @nums[-1] == nil
            raise "calculator is empty"
        else
        @value = @nums[-2].to_f / @nums[-1].to_f
        @nums.pop(2)
        @nums.push(@value)
        end
    end

    def times
        if @nums[-2] == nil || @nums[-1] == nil
            raise "calculator is empty"
        else
        @value = @nums.pop.to_f * @nums.pop.to_f
        @nums.push(@value)
        end
    end

    def value
        @nums #Don't understand why @nums.pop won't work here
    end

    def tokens(str)
        str.split(" ").map { |char| (char.match(/\d/) ? char.to_i : char.to_sym)}
    end

    def evaluate(str)

        tokens(str).each do |x| 

            if x == ":-"
                minus

            elsif x == ":+"
                plus

            elsif x == ":/"
                divide

            elsif x ==":*"
                times

            else
                push(x) 
            end
        end
        value
    end 
end

错误与规范的以下部分有关:

it "adds two numbers" do
    calculator.push(2)
    calculator.push(3)
    calculator.plus
    calculator.value.should == 5
end

错误说明:

Failure/Error: calculator.value.should == 5
expected: 5
got: [5] <using ==>

或者如果使用 .pop

Failure/Error: @calculator = RPNCalculator.new
NoMethodError:
undefined method 'pop' for nil:NilClass

【问题讨论】:

  • 请记住,在 Ruby 中,仅有的两个逻辑错误值是 nilfalse。这使得使用== nil.nil?nil 进行直接比较几乎总是多余的。 unless @nums[-2] &amp;&amp; @nums[-1] 比你这里的更好。

标签: ruby


【解决方案1】:

分配@value = value 的初始化方法调用def value 处的函数,该函数返回@nums,它在初始化中尚未创建,因为@nums 是随后用nums ||= []; @nums = nums 创建的,因此它是无。这就是 .pop 不起作用的原因。

您已将 @nums 创建为带有 nums ||= [] 的数组,并且您将它与 push 和 pop 一起使用,那么为什么在调用 value 返回时使用 value.should == 5 (Integer) 检查值数组)。您需要像 value.first.should == 5 或 value[0].should == 5 一样编写它...否则您应该更改 value 以仅返回您想要的元素

def value
  @nums.pop # or @nums[0], or @nums.first or @nums.last however you plan on using it
end

问题在于您的初始化方法中的 @value = value。修复该问题,然后您可以添加 .pop in 值。

编辑

此外,您的评估是在使用值填充 @nums 之前调用方法。然后方法“引发”错误。只有一个值被推送到 @nums 后,您不能调用减号。

这就是我将如何处理拆分字符串的流程

# Multiplication and Division need to happen before addition and subtraction
mylist = "1+3*7".split(/([+|-])/)
=> ["1", "+", "3*7"] 

# Compute multiplication and division
mylist = mylist.map {|x| !!(x =~ /[*|\/]/) ? eval(x) : x }
=> ["1", "+", 21]

# Do the rest of the addition
eval mylist.join
=> 22

我意识到这并不是您要解决的问题...但我认为按数学序列的顺序拆分将是正确的方法。所以首先计算 () 之间的所有内容,然后只计算乘法和除法,然后计算所有加法和减法。

编辑 我刚刚研究了 RPN 计算器是什么。所以不要介意我的拆分建议,因为它不适用。

【讨论】:

  • 由于我不希望程序在初始化时调用value方法,所以我认为我应该将变量“value”更改为“sum”。然而,这现在正在引起另一个我也不理解的连锁反应。我应该重新粘贴显示的代码吗?因为现在我在规范的不同部分遇到错误(错误:计算器为空):它“添加三个数字”docalculator.push(2)calculator.push(3)calculator.push(4)calculator.plus计算器.value.should == 7 计算器.plus 计算器.value.should == 9 结束
  • 尝试将值设置为 nil 或 0。所以@value = 0。这样你就不会调用 value 方法。
  • 这也导致我在添加三个数字时出现“计算器为空”的错误
  • 2.1.2 :101 > x.push 2 => [2] 2.1.2 :102 > x.push 3 => [2, 3] 2.1.2 :103 > x.push 4 => [2, 3, 4] 2.1.2 :108 > x.plus => [2, 7] 2.1.2 :109 > x.plus => [9] 你的 plus 功能有效。你必须这样做吗?因为在 Ruby 中有更简单的方法可以做到这一点。
  • 如果我是你,我会改变你的方法来使用注入。例如 @nums.inject(:+)@nums.inject(:*)@nums.inject(:-)@nums.inject(:/) ...这将对数组中的所有项目进行数学运算。
猜你喜欢
  • 2020-11-03
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-26
  • 1970-01-01
  • 2019-10-04
相关资源
最近更新 更多