如何在模块中初始化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。不管谁投了反对票,你能解释一下吗?