模块,定义允许包含调用超级的方法

时间:2016-07-05 18:47:58

标签: ruby

假设我想要一个接口:

class SomeModel
  include MagicModule

  attribute :some_method1
  attribute :some_method2

  def some_method1; super end
end

MagicModule就像:

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

 module ClassMethods
  def attribute(attribute_name)
    define_method(attribute_name) { attribute_name.to_s }
  end
 end 
end

如何使MagicModule工作以使def some_method1; super end以上工作?


我尝试过这样的事情:

module MagicModule
 extend ActiveSupport::Concern

 included do
    hidden_module = Module.new do
      def hidden_module; method(__callee__).owner end
    end
    extend hidden_module
 end

 module ClassMethods
  def attribute(attribute_name)
    hidden_module.send(:define_method, attribute_name) { attribute_name.to_s }
  end
 end 
end

但没有运气。

1 个答案:

答案 0 :(得分:2)

创建包含访问器的模块的想法是正确的(例如,这是rails为其自动生成的访问器所做的事情)。但是,您希望包含模块而不是扩展它

module MagicModule
  def self.included(base)
    base.send(:extend, ClassMethods)
  end

  module ClassMethods
    def attribute(attribute_name)
      unless @hidden_module
        @hidden_module = Module.new
        include @hidden_module
      end
      @hidden_module.send(:define_method, attribute_name) { attribute_name.to_s }
    end
  end 
end

我已经在创建模块的地方移动了所以如果您继承SomeModel,您仍然可以在该子类上定义新属性。