3

考虑以下代码

class CheckOut 
    @rules
    @total = 0
    @basket = Hash.new 

    def initialize(rules, discounts)
        @total=0
                #if i use the line below everything is ok.
        #@basket = Hash.new
        @rules = rules
    end

     def scan sku
          price = @rules[sku]
          if @basket.has_key?(sku) #I get NoMethodError: undefined method `has_key?' for nil:NilClass
             @basket[sku] += 1
          else 
              @basket[sku] = 1
          end
          @total += price
     end    

     def total
        @total
     end
end

如果我按原样运行代码,我会在 has_key 上得到 noMethodError?但是如果我在初始化时创建哈希,一切正常。为什么我不能在声明时创建哈希?

4

1 回答 1

8

当你在类体中定义一个实例变量时,它是一个定义在 上的类实例变量CheckOut,它是 的实例Class,并且不存在于 的实例中CheckOut。相反,您需要在您initialize发现的情况下定义实例变量(因为initialize在新CheckOut实例的上下文中运行):

class CheckOut
  def initialize(rules, discounts)
    @total = 0
    @basket = Hash.new
    @rules = rules
  end
  ...
end

这是一个进一步说明这一点的快速示例:

class Foo
  @bar = "class bar!"
  @baz = "class baz!"
  def initialize
    @bar = "instance bar!"
  end
end

Foo.instance_variable_get(:@bar)  #=> "class bar!"
Foo.new.instance_variable_get(:@bar)  #=> "instance bar!"

Foo.instance_variable_get(:@baz)  #=> "class baz!"
Foo.new.instance_variable_get(:@baz)  #=> nil

这也表明所有实例变量都默认为nil,即使它们以前从未被引用过。这就是为什么您的错误是 aNoMethodError for nil:NilClass而不是 a 的原因NameError

于 2012-04-29T22:17:26.980 回答