假设我想要一个接口:
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
但没有运气。
答案 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
,您仍然可以在该子类上定义新属性。