Why can't I create my private variable where I declare it?

Consider the following code

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

If I run the code as is, do I get noMethodError on has_key? but if I create a Hash to initialize, everything will work. Why can't I create a hash in an ad?

+3
source share
1 answer

When you define an instance variable in a class cube, it is a class instance variable defined on CheckOut, which is an instance Classand does not exist in the instance CheckOut. Instead, you need to define the instance variables in yours initialize, as you have already found (since it initializeexecutes in the context of the new instance CheckOut):

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

Here is a brief example to illustrate this further:

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, . NoMethodError for nil:NilClass, NameError.

+8

All Articles