如何在模块中初始化ruby类变量
假设我有这样的代码:如何在模块中初始化ruby类变量,ruby,Ruby,假设我有这样的代码: class TestClass module ClassMethods attr_accessor :number def initialize @number = 47 end end include ClassMethods extend ClassMethods end class TestClass module ClassMethods attr_accessor :number de
class TestClass
module ClassMethods
attr_accessor :number
def initialize
@number = 47
end
end
include ClassMethods
extend ClassMethods
end
class TestClass
module ClassMethods
attr_accessor :number
def initialize
@number = 47
end
end
include ClassMethods
extend ClassMethods
@number = 47
end
TestClass.new.number
返回预期的47
,但TestClass.number
返回nil
如何为TestClass
类和TestClass
实例初始化number
变量?
到目前为止,我是这样做的:
class TestClass
module ClassMethods
attr_accessor :number
def initialize
@number = 47
end
end
include ClassMethods
extend ClassMethods
end
class TestClass
module ClassMethods
attr_accessor :number
def initialize
@number = 47
end
end
include ClassMethods
extend ClassMethods
@number = 47
end
我不喜欢这种方法,因为number
在两个地方初始化。假设您有这样一种方法:
class TestClass
module ClassMethods
attr_accessor :number
def initialize
@number = 47
end
end
include ClassMethods
extend ClassMethods
end
让我们了解一些关于这个类的信息:
TestClass.instance_variables #=> []
这并不奇怪
tc = TestClass.new #=> #<TestClass:0x00000101098a10 @number=47>
p tc.instance_variables #=> [:@number]
tc.number #=> 47
tc.number = 11
啊,是的,initialize
是一个私有方法
TestClass.methods.include?(:initialize) #=> false
TestClass.private_methods.include?(:initialize) #=> true
我们不能以通常的方式调用私有类方法<但是,code>send可用于私有和公共方法:
TestClass.send :initialize #=> 47
TestClass.instance_variables #=> [:@number]
TestClass.instance_variable_get(:@number) #=> 47
因此,现在创建的类实例变量设置为47
。它是否更改了实例变量@number
的值
tc.number #=> 11
它没有改变。现在,让我们更改class实例变量的值,然后查看实例变量的值是否受到影响:
TestClass.instance_variable_set(:@number, -5) #=> -5
tc.number #=> 11
如果要为类实例变量@number
添加访问器,请将此行添加到类或模块:
Module.instance_eval("attr_accessor :number")
(有关解释,请参阅我的答案。)
然后测试:
TestClass.number #=> -5
TestClass.number = 107
TestClass.number #=> 107
第一个数字用于
TestClass
的给定实例;第二个是类实例变量。它们可以共存,因为它们就像@night
和@day
@CarySwoveland一样不同:我理解这一点。我的问题是为什么“扩展类方法”不初始化类实例变量。如何在没有重复代码的情况下同时初始化实例变量和类实例变量?xx,我没有忘记。我花了一段时间才找到答案。如果您有任何问题,请告诉我。谢谢,我的思路是正确的,只是我尝试在不使用send的情况下调用initialize。不管谁投了反对票,你能解释一下吗?