动态添加的实例方法无法访问类变量

时间:2016-03-08 07:41:25

标签: ruby

(问题已经发布在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

在警告和错误消息中提及toplevelObject令我感到困惑。

@x打印为5,因此其环境为MC。这排除了@x定义中@@ym.g引用顶层环境(Object)而不是MC的可能性。

为什么我收到错误消息?

2 个答案:

答案 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}}定义的单例方法。