问题描述
我正在尝试编写一个通用模块,以将用于动态方法创建的 method_missing 模式应用于我的某些 Rails 模型.这些模型具有类方法和实例方法.虽然我可以为这两种情况相当简单地编写一个模块:
I'm trying to write a general purpose module to apply the method_missing pattern for dynamic method creation to some of my Rails models. These models have both class methods and instance methods. While I can write a module fairly straightforwardly for either the class case:
module ClassVersion
extend ActiveSupport::Concern
module ClassMethods
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
end
end
或实例案例:
module InstanceVersion
extend ActiveSupport::Concern
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
end
...我似乎无法在同一班级中同时支持这两种情况.有没有更好的方法来覆盖 method_missing 以便支持这两种情况?我在 Rails 3.2 上......
... I can't seem to support both cases in the same class. Is there a better way to override method_missing such that both cases are supported? I'm on Rails 3.2....
推荐答案
您要实现的目标非常简单,同时又不寻常.ActiveSupport::Concern
为您提供了定义嵌套 ClassMethods
模块的可能性,该模块扩展了 included
模块挂钩上的基类.通常这很方便,因为您不想用相同的方法扩充类及其实例.
What you are trying to achieve is pretty straightforward, and unusual at the same time. ActiveSupport::Concern
is giving you possibility of defining nested ClassMethods
module that is extending base class on included
module hook. Usually this is handy, because you don't want to augment both class and its instances with the same methods.
您需要做的是停止使用 ActiveSupport::Concern
并编写 included
钩子来满足您的特定需求:
What you need to do is stop using ActiveSupport::Concern
and write included
hook to meet your particular needs:
module AsyncModule
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
private
def self.included(base)
base.extend self
end
end
这篇关于覆盖类和实例方法的method_missing?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!