为什么这个实例变量没有递增?

时间:2016-10-24 18:45:53

标签: ruby

当我使用类变量@@points而不是@points时,此短代码正常工作。我想知道为什么会这样发生?有人可以解释一下吗?看起来@points总是nil

class Game

  @points = 0

  def start

    until @points == 10
      puts "Guess number between 0 and 10:" 
      num = gets.chomp.to_i
      break if @points == 0
      guess_number(num)
      puts "Your score is: #{@points}"

    end

  end

  def guess_number(num)
    @points += 1 if num == rand(0..10)
  end

end

game = Game.new
game.start

2 个答案:

答案 0 :(得分:2)

因为UINavigationController是一个类实例变量,并且要从实例方法的范围内访问它,你必须要做

@points

或在self.class.instance_variable_get(:@points) 的singleton_class中定义attr_accessor

Game

然后你就可以了

class Game; class << self; attr_accessor :points; end; end

但这些都不是你真正想要的。

  当我使用类变量self.class.points 代替时,

代码正常工作   @@points

它正在工作,因为您可以在实例方法的范围内访问类变量。

  

看起来@points总是@points

始终为nil,因为您从未定义过实例变量nil,但正如所说的那样,是类实例变量。

所以这三件事情是不同的(你可以读一些关于Ruby范围的东西 - 不要与AR范围混合):

  • 类变量
  • 类实例变量
  • 实例变量

要解决它有很多种方法,但如果你想将它保留在实例级别,请将@points包装到方法中:

@points

然后将其用作def points @points ||= 0 end - 现在它可以按照您的预期运作。

答案 1 :(得分:0)

感谢Andrey Deineko的回答。我想出了这样的解决方案,在这里使用实例变量。

class Game

  def initialize
    @points = 0
  end

  def start

    until points == 10
      puts "Guess number between 0 and 10:" 
      num = gets.chomp.to_i
      break if points == 10
      guess_number(num)
      puts "Your score is: #{points}"

    end

  end

  private

  def guess_number(num)
    if num == rand(0..10)
      increment_points
    end
  end

  def points
    @points
  end

  def increment_points
    @points += 1
  end

end

game = Game.new
game.start