class_eval和类变量的上下文?

时间:2014-07-02 20:05:11

标签: ruby inheritance metaclass

寻找解释为什么在Module.class_eval块中的以下示例中,类变量查找不起作用:

class MyClass
  @@myvar = 123
  def self.myvar_getter
    @@myvar
  end
end

class MyClass
  p "#{self}, #{self.object_id}, #{singleton_class.object_id}"
  # output: "MyClass, 21055520, 21055500"
  p myvar_getter  # class method lookup working
  # output: 123
  p @@myvar       # class variable lookup working
  # output: 123
end

MyClass.class_eval do
  p "#{self}, #{self.object_id}, #{singleton_class.object_id}"
  # output: "MyClass, 21055520, 21055500"
  p myvar_getter  # class method lookup working as expected
  # output: 123
  p @@myvar       # class variable lookup NOT working (why ?)
  # output: -- following exception --
  #   a.rb:47: warning: class variable access from toplevel
  #   a.rb:47:in `block in <main>': uninitialized class variable
  #   @@myvar in Object (NameError)
end

正如您可能看到范围似乎相同,self是相同的,在两种情况下都找到了类方法:myvar_getter,但在@@myvar中意外查找了类变量Object {1}} class_eval块内的类。 任何人都可以解释除之外的其他行为,因为

1 个答案:

答案 0 :(得分:0)

我必须经历一些微弱的时刻,因为答案非常清楚&amp;明显。

来自Module.class_eval文档:

在mod 的上下文中计算字符串或块,但在a时除外 给出了块,常量/类变量查找不受影响。这可以 用于向类添加方法。 module_eval返回评估结果 它的论点。

因此,如果我需要直接从eval块访问类变量(即不使用类变量getter / setter方法),我只需将代码作为字符串传递:

MyClass.class_eval <<-EOS
  p @@myvar       # class variable lookup is working from a string
  # output: 123  voila!
  EOS