以下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]
?
答案 0 :(得分:2)
class << self
attr_accessor :member
end
不会像您期望的那样为@@member
创建读者/作者,而是在类级别创建@member
。
类是实例(Class),因此它们也有实例变量。
@@
变量是一个特殊的东西 - 一个可以从类和实例范围访问的变量(也可以通过iheritance链共享) - 并且与类的实例变量不同。
如果您想要类变量的读/写器,您必须手动编写(例如def member
和def member=(val)
中的class << self
和require '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