类实例变量在扩展模块中初始化

时间:2017-08-29 09:15:10

标签: ruby

我知道应该有一种方法来初始化由模块通过extend添加的类实例变量 例如:

module MyModule
  def self.included(base)
    base.extend ClassMethods
    base.send :include, InstanceMethods
  end

  module ClassMethods
    attr_accessor :count

    def self.count
      @count = 0
    end

    count
  end

  module InstanceMethods
    def register
      # self.class.count = 0 if self.class.count.nil?
      self.class.count += 1
    end
  end
end

class Foo
  include MyModule

  private

  def initialize
    register
  end

end

在ClassMethods中应该是一种初始化count的方法,但我总是会遇到错误"未定义的方法`+'为零:NilClass" 当我表演时

f = Foo.new

如果我取消注释行

,模块InstanceMethods没问题
# self.class.count = 0 if self.class.count.nil?

正常工作!

2 个答案:

答案 0 :(得分:4)

您可以将变量初始化移动到included回调:

module MyModule
  def self.included(base)
    base.extend ClassMethods
    base.include InstanceMethods
    base.count = 0
  end

  module ClassMethods
    attr_accessor :count
  end

  module InstanceMethods
    def register
      self.class.count += 1
    end
  end
end

答案 1 :(得分:3)

代码中有一点self。您已经extendClassMethods个模块。 extend使用实例方法,而不是类方法。所以你的模块应该是这样的(其余的代码没有改变)。

module ClassMethods

  def count
    @count ||= 0
  end

  attr_writer :count
end

然后它可以工作

Foo.count # => 0
Foo.new
Foo.count # => 1