为什么我的实例变量不存在于ruby中同一类的方法中?

时间:2013-09-18 03:53:51

标签: ruby instance-variables class-instance-variables

我正在做ruby koans,我在DiceSet项目上。我已经创建了DiceSet类,但我的实例变量似乎并没有像我想的那样持久存在。我的代码是

class DiceSet
   attr_reader :values
   @values = []
   puts @values.class
   def roll(number_of_rolls)
     (1..number_of_rolls).each do |roll|
       puts @values.class
       @values << (1..6).to_a.sample
     end
     return @values
   end
end

然后koan将我的DiceSet类与

一起使用
dice = DiceSet.new
dice.roll(5)
puts dice.values.class
assert dice.values.is?(Array)

我将puts命令放在那里以跟随@values实例变量发生的事情,只有第一个puts @ values.class表示它是一个Array类。所有其他人都返回NilClass。我是否错误地使用了实例变量,还是我还缺少其他东西?实例变量是否在方法调用后被释放?

编辑:我的类正常工作,因为我已将@values = []放在roll方法中,如下所示。我现在唯一的问题是,当我在初始化方法中放入@values = []时,roll方法认为@values是NilClass而不是数组

4 个答案:

答案 0 :(得分:1)

在Ruby中,一切都是对象。 Ruby解释器假定所有实例变量都属于当前对象 self 。在类定义中也是如此。 self 的作用属于类本身,因此实例变量@values属于该类。不要混淆!该类的实例变量与实例不同 该类对象的变量。此外,您不需要明确指定return关键字试试这个:

class DiceSet
   attr_accessor :values       

   def roll(number_of_rolls)
     @values = []
     (1..number_of_rolls).each do |roll|
       @values << (1..6).to_a.sample
     end
     @values
   end
end

dice = DiceSet.new
dice.roll(5)
puts dice.values.class
assert dice.values.is_a?(Array)

答案 1 :(得分:0)

每个DiceSet个实例都有自己的@values,此外,类DiceSet也有自己的@values。它们彼此不同。如果希望实例和类共享同一个变量,则应使用类变量@@values

答案 2 :(得分:0)

试试这个:

class Cat
  attr_accessor :age
  def initialize
    @age = 12
  end
  @age = 6
  def meow
    puts "I'm #{@age}"
  end
  def self.meow
    puts "I'm #{@age}, going on #{@age+1}"
  end    
end
Cat.age = 4 # => NoMethodError: undefined method `age=' for Cat:Class
p Cat.age # =? NoMethodError: undefined method `age' for Cat:Class
Cat.meow # => I'm 6, going on 7
cat = Cat.new
p cat.age # => 12
cat.meow # => I'm 12
cat.age = 20 # => 20
cat.meow # => I'm 20

我要添加

class << self
   attr_accessor :age
end

前三行输出将成为:

Cat.age = 4 # => 4
p Cat.age # => 4
Cat.meow # => I'm 4, going on 5

答案 3 :(得分:0)

只需将@values = []的声明放在初始化方法中,您的代码应该按预期工作。

class DiceSet

  attr_reader :values
  def initialize()
     @values = []
  end

  def roll(number_of_rolls)
    (1..number_of_rolls).each do |roll|
      puts @values.class
      @values << (1..6).to_a.sample
    end
    return @values
  end
end
相关问题