如何在Ruby的扩展模块中使用类实例变量?

时间:2017-08-13 16:23:52

标签: ruby metaprogramming

我想创建一个存储各种块的DSL,然后可以调用它们。我希望这是一个可重用的模块,我可以包含在多个类中。

我想出了一种使用类变量的方法,但rubocop抱怨并说我应该使用类实例变量。我无法找到一种方法来做到这一点。有可能吗?

module MyModule
  def self.included(base)
    base.extend(ClassMethods)
  end

  def run_fixers
    ClassMethods.class_variable_get(:@@fixers).each(&:call)
  end

  module ClassMethods
    def fix(_name, &block)
      @@fixers ||= []
      @@fixers << block
    end
  end
end

class MyClass
  include MyModule

  def initialize
    run_fixers
  end

  fix 'test' do
    puts 'testing'
  end
end

1 个答案:

答案 0 :(得分:2)

Rubocop抱怨@@class_variable风格。可以使用类的实例变量将类变量用法重构为:

class SomeClass
  @some_variable ||= []
end

而不是

class SomeClass
  @@some_variable ||= []
end

您可以在self等于类对象的任何位置定义类的实例变量。例如,在类方法中:

module MyModule
  def self.included(base)
    base.extend(ClassMethods)
  end

  def run_fixers
    ClassMethods.fixers.each(&:call)
  end

  module ClassMethods
    def self.fixers
      @fixers ||= []
    end

    def fix(_name, &block)
      ClassMethods.fixers << block
    end
  end
end