Как обезьяна патч класса включенного модуля? - PullRequest
0 голосов
/ 10 октября 2019

У меня есть драгоценный камень с классом, который динамически включает модули. Мне нужно переопределить все методы в этих модулях, чтобы вставить дополнительную логику (для отслеживания метрик)

Пример класса:

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 в этом контексте не работает. Это решило проблему для меня.

1 Ответ

0 голосов
/ 10 октября 2019

Я смог решить эту проблему, сначала наложив псевдоним исходного метода, а затем вызвав псевдоним в моем переопределенном методе.

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 в этом контексте не работает. Это решило проблему для меня.

...