【发布时间】:2017-11-28 07:26:34
【问题描述】:
假设我有一个模块XYZ。当包含在一个类中时,它会扩展基类并在其中添加一个类变量@@foo。它还使用方法扩展类以执行一些get 和set。
module XYZ
def self.included(base)
base.send :extend, ClassMethods
base.class_eval do
@@foo ||= []
end
end
module ClassMethods
def foo
class_variable_get("@@foo")
end
def foo=(arg)
class_variable_set("@@foo", arg)
end
def dynamic_set(*args)
foo += args # This doesn't work
end
def dynamic_set_2(*args)
class_variable_set("@@foo", class_variable_get("@@foo") + args)
end
end
end
现在,考虑一下用法:
class A
include XYZ
end
A.foo #=> []
A.class_variable_get("@@foo") #=> []
A.dynamic_set 1, 2 #=> NoMethodError: undefined method `+' for nil:NilClass
A.dynamic_set_2 1, 2 #=> [1,2]
A.foo #=> [1,2]
A.class_variable_get("@@foo") #=> [1,2]
sn-p 有意义并且可以完成工作,但我无法弄清楚为什么 A.dynamic_set 1, 2 不起作用。
来到问题的主要部分 - 如果我将新的 class B 定义为:
class B
include XYZ
end
B.foo #=> [1,2] => Why? How did B.foo get these values?
B.class_variable_get("@@foo") #=> [1,2] => Why?
B.dynamic_set_2 3, 4
B.foo #=> [1,2,3,4]
A.foo #=> [1,2,3,4]
当@@foo 在类级别定义时(使用class_eval),为什么B 和A 共享同一个类变量?
我了解使用类变量和类实例变量的含义。只是想弄清楚为什么这不能按预期工作,以清除一些概念:)
【问题讨论】:
-
类变量就是这样工作的。
-
@sawa:在类层次结构中,是的。但为什么在这里?
标签: ruby