【问题标题】:Why are my instance variables not existing across methods of the same class in ruby?为什么我的实例变量不存在于 ruby​​ 中同一类的方法中?
【发布时间】:2013-09-22 16:48:53
【问题描述】:

我正在做 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 而不是数组

【问题讨论】:

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


    【解决方案1】:

    试试这个:

    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
    

    【讨论】:

      【解决方案2】:

      只需将@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
      

      【讨论】:

        【解决方案3】:

        在 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)
        

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 2018-07-09
            • 2011-02-05
            • 1970-01-01
            • 2013-11-26
            • 2012-10-24
            • 2014-10-10
            • 1970-01-01
            • 2012-03-07
            • 1970-01-01
            相关资源
            最近更新 更多