(问题已经发布在Ruby Forum,但没有引起任何答案)。
这是我的代码:
class MC
def initialize
@x = 5
@@y = 6
end
def f
puts @x
puts @@y
end
end
m = MC.new
m.f
m.f
产生预期的输出而没有错误:
5
6
但是这个:
def m.g
puts @x
puts @@y
end
m.g
产生
5
warning: class variable access from toplevel
NameError: uninitialized class variable @@y in Object
为什么我可以从@@y
访问f
,而不是g
?
在警告和错误消息中提及toplevel
和Object
令我感到困惑。
@x
打印为5
,因此其环境为MC
。这排除了@x
定义中@@y
和m.g
引用顶层环境(Object
)而不是MC
的可能性。
为什么我收到错误消息?
答案 0 :(得分:5)
以下所有变体都有效:
def m.g; puts self.class.send(:class_eval, '@@y') end
def m.g; puts self.class.class_variable_get(:@@y) end
class << m; def g; puts self.class.send(:class_eval, '@@y') end end
class << m; puts class_variable_get(:@@y) end
但这些失败了:
def m.g; puts @@y; end
class << m; puts class_eval('@@y') end
我认为这是一个红宝石解析器故障。
答案 1 :(得分:4)
您不会在类g
中创建MC
,而是在m
的单例类(a.k.a.eigenclass)中创建m
。
这是一个专门为对象m
存在的类,用于存储仅为{{1}}定义的单例方法。