为什么班级变量的价值' nil'在红宝石?

时间:2018-03-29 01:21:52

标签: ruby

以下ruby脚本:

require 'pp'
class BB
    @@member = [100, 200]

    class << self
        attr_accessor :member
    end

    def setm(m)
        self.class.member = m
    end

    def setm2(m)
        @@member = m
    end

    def look(i)
        pp "ites was : #{@@member[i]}"
    end
end

pp BB.member     # nil, Why not [100, 200]?
t = BB.new
t.look 0         # item was: 100
t.look 1         # item was: 200
t.setm [200, 300]
pp BB.member     # [200, 300]

t.setm2 [400,500]
pp BB.member     # [200 , 300]  , Why not [400,500]

我跑了。输出是:

$ ruby t.rb
nil
"ites was : 100"
"ites was : 200"
[200, 300]
[200, 300]

为什么第一个pp BB.member nil的输出而不是[100, 200]?为什么是最后一个pp BB.member [200, 300],而不是[400, 500]

2 个答案:

答案 0 :(得分:2)

基本上是这样的:

class << self
    attr_accessor :member
end

不会像您期望的那样为@@member创建读者/作者,而是在类级别创建@member

类是实例(Class),因此它们也有实例变量。

@@变量是一个特殊的东西 - 一个可以从类和实例范围访问的变量(也可以通过iheritance链共享) - 并且与类的实例变量不同。

如果您想要类变量的读/写器,您必须手动编写(例如def memberdef member=(val)中的class << selfrequire 'active_support/all',或者{{{ 1}}你可以使用:

class Foo
  cattr_accessor :member
end

在这种情况下,从实例方法调用@@member =或调用Foo.member =修改相同的值。

答案 1 :(得分:0)

你在做什么有所不同。一个是类变量,另一个是单例类的实例变量。

不确定您想要实现的行为,但看看是否有类似于以下习语的行为。

  class Foo

    class << self
      @@bar = :bar
      def bar
        @@bar
      end
    end
  end