类方法的实例变量的范围

时间:2015-08-21 18:51:25

标签: ruby class variables scope

我正在尝试使用以下代码。

class Animal

end

class Tiger < Animal
    @hunger = 100

    def self.hunger
        @hunger 
    end

    def run
        puts "The Tiger runs"
        @hunger += 10
    end
end

class Statistics
    puts "This tigers hunger is: #{Tiger.hunger}" 
end

tiger = Tiger.new()
tiger.run

因此,老虎有一个名为hunger的变量,它本身位于Tiger类的顶部。我想这样做,所以这个变量可以在整个类方法中改变。例如,在run中,饥饿设置为hunger += 10,但是当我运行此代码时,我得到undefined method '+' for nil:NilClass (NoMethodError)。我该怎么做才能让这个程序工作,这样变量就可以改变,然后显示在Statistics类中?

3 个答案:

答案 0 :(得分:2)

问题在于你将类和实例变量/方法完全混合在一起。

如果你想使用实例(你应该):

class Animal; end

class Tiger < Animal
  attr_reader :hunger

  def initialize
    @hunger = 100
  end

  def run
    puts "The Tiger runs"
    @hunger += 10
  end
end

class Statistics
  def self.show(tiger)
    puts "This tigers hunger is: #{tiger.hunger}" 
  end
end

tiger = Tiger.new
tiger.run
Statistics.show(tiger)

如果你想使用类方法/变量:

class Animal; end

class Tiger < Animal
  @hunger = 100

  def self.hunger
    @hunger
  end

  def self.run
    puts "The Tiger runs"
    @hunger += 10
  end
end

class Statistics
  def self.show
    puts "This tigers hunger is: #{Tiger.hunger}" 
  end
end

Tiger.run
Statistics.show

请注意,@hunger现在是Tiger的类实例变量。类实例变量和类变量(用@@定义的变量)之间的区别在于后者由所述类的所有后代共享,而前者仅与定义它的类相关联。

我不同意你们在任何一种情况下关于Statistic的决定。

答案 1 :(得分:1)

你的Tiger课程中不需要初始化方法吗?

def initialize()
@hunger = 100
end

我对你的统计课很困惑。这不应该是Tiger课程中的方法吗?它如何知道Tiger要访问什么?我想补充一点,如果你想这样做,就把你的老虎作为一个参数。

class Statistics
def tiger_stat(tiger_name)
puts "This tigers hunger is: #{tiger_name.hunger}" 
end
end

编辑*这是我将使用的代码:

class Animal
    def initialize(animal_type, hunger_start)
        @animal_type = animal_type
        @hunger = hunger_start
    end

    def hunger_print
        puts "This #{@animal_type}'s hunger is: #{@hunger}."
    end
end

class Tiger < Animal
    def initialize
        super("Tiger", 100)
    end

    def run
        puts "The Tiger runs"
        @hunger += 10
    end
end

通过这种方式,您可以在任何动物身上调用hunger_print而无需担心类型或进行额外课程。你可以做类似的事情。

tiger = Tiger.new
tiger.run
tiger.hunger_print

答案 2 :(得分:0)

您可以使用从实例和类方法访问的类变量。

class Animal
  @@hunger = 100

  def self.hunger
    @@hunger
  end

  def self.increase_hunger
    @@hunger +=1
  end

  def hunger
    @@hunger
  end

  def increase_hunger
    @@hunger += 1
  end
end

Animal.increase_hunger
puts Animal.hunger # => 101
animal = Animal.new
animal.increase_hunger
puts animal.hunger # => 102