Как правильно выполнить monkeypatch Ruby?

#ruby #ruby-on-rails-3 #monkeypatching

#ruby #ruby-on-rails-3 #исправление обезьян

Вопрос:

Я пытаюсь выполнить monkeypatch строку в классе Net в стандартной библиотеке. Я создал файл под названием patches.rb в папке lib проекта и добавил это

 module Net
  class HTTP < Protocol
    module HTTPHeader
      def initialize_http_header(initheader)
        @header = {}
        return unless initheader
        initheader.each do |key, value|
          @header[key.downcase] = [value.strip] rescue ""
        end
      end
    end
  end
end
  

Но это не работает. Правильно ли я это делаю? (Это в точности соответствует иерархии наследования.)

Редактировать: частично проблема заключалась в том, что мне пришлось поместить файл в папку initalizers. Но все еще вижу ту же ошибку.

Комментарии:

1. что вы тогда делаете require 'lib/patches' ?

2. @caley Я думал, что все в папке lib загружается автоматически при загрузке.

3. Извините, это так, я думал, вы имели в виду папку lib вашего создания.

4. @taro: ошибка — это whiny_nil, от которой я пытаюсь избавиться. Пока я вижу ошибку, это означает, что мой патч не переопределяет оригинал.

Ответ №1:

Поскольку вещи в lib/ каталоге загружаются только по запросу, вы можете добиться большего успеха, поместив подобные исправления в config/initializers/ , где они автоматически загружаются после инициализации стека.

Вы также можете свернуть определение расширений до чего-то вроде этого:

 module Net::HTTP::HTTPHeader
  # ... (redefined methods) ...
end
  

Комментарии:

1. Спасибо, тэдман. Я свернул определение, но выполняемый код по-прежнему, похоже, исходит из источника кода.

2. Может быть легко выполнить monkeypatch неправильно, поэтому вы всегда должны дважды проверять пространство имен вашей цели. Я заглянул в net/http.rb и, вероятно, должно быть Net::HTTPHeader , что вы переопределяете методы в, а не Net::HTTP::HTTPHeader .