Куда ставить код при исправлении обезьяны

Все, что я читал о патчах обезьян, говорит о том, что нужно делать что-то вроде этого:

class String
  def foo
    #your special code 
  end
end

Но я не могу найти никаких инструкций, где разместить этот код. Могу ли я поместить это в любое безумное место в приложении для рельсов? В модуле? Модель?

Нужно ли мне что-то включать в файл, в котором я определяю свой monkeypatch? Нужно ли мне включать обезьяну повсюду, где я хочу ее использовать?


person Life4ants    schedule 17.01.2017    source источник
comment
Я бы рекомендовал вам прочитать об уточнениях. Они разработаны, чтобы помочь избежать проблем, которые мы наблюдаем при установке исправлений для обезьян.   -  person the Tin Man    schedule 18.01.2017
comment
Прежде чем пойти по этому пути, подумайте о создании подкласса String, который будет делать то, что вы хотите. Это нужно делать только тогда, когда вам нужно изменить поведение вещей повсеместно.   -  person tadman    schedule 18.01.2017


Ответы (3)


На этот счет нет установленных правил. Технически вы можете открыть его (класс и добавить свой метод) где угодно. Обычно я создаю специальный файл с именем monkey_patches.rb и помещаю его в config/initializers или misc папку в моем приложении Rails, поэтому, если возникнет конфликт, я знаю, где искать.

Также я бы посоветовал использовать Module, чтобы обернуть патч обезьяны. Ознакомьтесь с 3 способа исправления обезьяны без беспорядок, чтобы получить дополнительную информацию.

Его пример:

module CoreExtensions
  module DateTime
    module BusinessDays
      def weekday?
        !sunday? && !saturday?
      end
    end
  end
end

DateTime.include CoreExtensions::DateTime::BusinessDays
person virtuexru    schedule 17.01.2017
comment
Я действительно пытаюсь дать файлам config/initializers какое-нибудь осмысленное имя, например, в данном случае business_days.rb, вместо чего-то общего, например, monkey_patches.rb или embarrassing_collection_of_unfortunate_hacks.rb. Если у вас есть редактор, который позволяет быстро открывать по имени, его легко открыть, если вам когда-либо придется вносить изменения, если их имя согласуется. - person tadman; 18.01.2017

Я использовал следующую технику, описанную Джастином Вайсом в 3 способа исправить обезьяну, не создавая беспорядка

В ванильном Ruby, например, геме, вы определяете модуль в каком-то файле, который вам нужен, а затем _ 1_ (или extend) модуль в желаемый класс.

module StringMonkeypatch
  def foo
    #your special code 
  end
end

String.include StringMonkeypatch

Находясь в Rails, вы можете захотеть определить модуль в месте, которое загружается автоматически (ищите autoload_paths) и в соответствии с соглашением об именах Rails.

Например, если обезьяна исправляет класс Sidekiq::Testing gem, вы должны отразить файловую структуру.

# in /app/<something telling>/sidekiq/testing/monkeypatch.rb
module Sidekiq::Testing::Monkeypatch
  def foo
    #your special code 
  end
end

# in /config/environment.rb, at the bootom
Sidekiq::Testing.include Sidekiq::Testing::Monkeypatch
person Epigene    schedule 05.10.2017

Просто вмешиваюсь, потому что мне потребовалась целая вечность, чтобы понять это, потому что очень маленькие решения работали.

• Мне пришлось использовать старый добрый require. Положил в config/application.rb файл. Файл не загружается для меня автоматически, если вы помещаете его в каталог приложения, как некоторые предлагают. Не знаю почему.

patching_file_path = File.expand_path("./lib", Dir.pwd) Dir[patching_file_path+'/*.rb'].each {|file| require file }

• Я также помещаю временный puts "I'm Working! в файл, который я пытаюсь потребовать, чтобы я мог проверить консоль, чтобы увидеть, действительно ли он загружается.

• Кроме того, если вы используете пружинный загрузчик, перед запуском консоли вы должны сделать bin/spring stop в своем терминале, прежде чем запускать консоль rails. В противном случае он не загрузит новые файлы.

person stephennelson    schedule 14.02.2019