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

クラス本体でインスタンス変数を定義すると、それはで定義されたクラスインスタンス変数であり、はのインスタンスであり、のインスタンスには存在しません。代わりに、見つけたとおりにインスタンス変数を定義する必要があります(新しいインスタンスのコンテキストで実行されるため)。CheckOutClassCheckOutinitializeinitializeCheckOut

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

これは、以前に参照されたことがない場合でも、すべてのインスタンス変数がデフォルトでデフォルトになっていることも示していますnilNoMethodError for nil:NilClassこれが、エラーがであり、ではない理由NameErrorです。

于 2012-04-29T22:17:26.980 に答える