本文介绍了覆盖类和实例方法的method_missing?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个通用模块,以将用于动态方法创建的 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 04:43