如何猴子修补 class 包含的模块?

How to monkey patch class included module?

我有一个 gem 和一个动态包含模块的 class。我需要覆盖这些模块中的所有方法以插入一些额外的逻辑(用于指标跟踪)

示例class:

module MyAPI
  class Client
    # This dynamically requires a bunch of modules  
    Dir[File.dirname(__FILE__) + '/client/*.rb'].each do |file|
      require file
      include const_get(File.basename(file).gsub('.rb','').split('_').map(&:capitalize).join('').to_s)
    end
  end
end

其中一个模块可能如下所示:

module MyAPI
  class Client
    module Companies

      def get_company(company_id, params = {})
        puts "original method"
      end

    end
  end
end

我需要在我的应用程序中修改它。我添加了一个新文件 /config/initializers/monkey_patches/my_api.rb

module MyAPI
  class Client
    module MonkeyPatchCompanies
      def get_company(company_id, params = {})
        puts 'Monkey Patched'
        super
      end
    end
    module Companies
      include MonkeyPatchCompanies
    end
  end
end

我已经尝试了与上述类似的各种方法来为包含的模块中的所有方法添加一些功能。

我试过的都没有成功。我得到类似的东西:

NoMethodError (undefined method `include?' for nil:NilClass)

猴子修补这样的东西的最佳方法是什么?

编辑:

我能够通过首先为原始方法别名,然后在我的重写方法中调用别名的原始方法来解决这个问题。

module_eval do
alias_method :get_company_old, :get_company
define_method :get_company do |*args|
  # My new code here
  send :get_company_old, *args
end

问题是 super 在这种情况下不起作用。这为我解决了这个问题。

我能够通过首先为原始方法添加别名,然后在我的重写方法中调用别名的原始方法来解决这个问题。

module_eval do
alias_method :get_company_old, :get_company
define_method :get_company do |*args|
  # My new code here
  send :get_company_old, *args
end

问题是 super 在这种情况下不起作用。这为我解决了问题。