看下面的代码:
class A
end
@class = eval("A")
@class.class_eval do
@@attr = 100
def self.get_attr
@@attr
end
def self.set_attr(_x)
p "hi"
@@attr = _x
end
end
class B
end
@class = eval("B")
@class.class_eval do
@@attr = 100
def self.get_attr
@@attr
end
def self.set_attr(_x)
p "hi"
@@attr = _x
end
end
a = A.new
b = B.new
A.set_attr(103)
B.set_attr(222)
p A.class_variable_defined?(:@@attr)
p B.class_variable_defined?(:@@attr)
p Object.class_variable_defined?(:@@attr)
p A.class_variable_get(:@@attr)
p B.class_variable_get(:@@attr)
p Object.class_variable_get(:@@attr)
p A.class_variables
p B.class_variables
Object.remove_class_variable(:@@attr)
p A.class_variables
p B.class_variables
输出:
true
true
true
222
222
222
[:@@attr]
[:@@attr]
[]
[]
说明:根据您的代码@@attr
属于Object
类类变量。并且根据Ruby
A 和 B 都是Object
. 因此类变量@@attr
已被共享。
Module#class_eval
说:
(a) 这可用于向类添加方法。
(b) 当给定一个块时,常量/类变量查找不受影响。
这是 ruby 的特性,如果你class variable
在里面使用class_eval
它会class variable
在类中搜索Object
。
为了使其可见,我编写了以下代码,这反过来将证明:常量/类变量查找不受影响。
@@avar = 1
class A < BasicObject
@@avar = "hello"
end
A.class_eval { puts @@avar }
查看代码输出:
D:/Rubyscript/My ruby learning days/Scripts/TEST.RB:91: warning: class variable
access from toplevel
D:/Rubyscript/My ruby learning days/Scripts/TEST.RB:95: warning: class variable
access from toplevel
1