【发布时间】:2014-08-23 18:34:47
【问题描述】:
寻找解释为什么在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,但是在 @987654329 内的 Object 类中意外查找了类变量 @@myvar @ 堵塞。
除了因为之外,任何人都可以解释这种行为吗?
【问题讨论】:
-
我认为这里的教训是类变量几乎永远不会按照您希望的方式运行。如果您对使用它们下定决心,则可以通过在相关类上明确使用
class_variable_get/set来找到更一致的结果。 -
@IronSavior 感谢您的评论。我知道
class_variable_get/set方法。我什至读过 Yehuda Katz 关于metaprogramming in Ruby 的精彩文章,其中描述了范围、方法解析和方法定义之间的细微差别。但是没有什么可以解释这个问题的问题。是否还有另一个概念可以区分变量查找? -
我隐约记得在某些情况下类变量的行为在 ruby 1.8 和 1.9 之间也不一致。它们可能有用例,但人们通常应该更喜欢在类的上下文中使用实例变量。 (为了以后遇到这个的人的利益)
标签: ruby inheritance metaclass