Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put code when monkey patching

Everything I read about monkey patching says to do something like this:

class String
  def foo
    #your special code 
  end
end

But I can't find any instructions on where to put this code. In a rails app, can I just put this any crazy place I want? In a Module? A Model?

Do I need to include something in the file where I define my monkeypatch? Do I need to include my monkeypatch everywhere where I want to use it?

like image 468
Life4ants Avatar asked Jan 17 '17 19:01

Life4ants


2 Answers

There is no set rule on this. Technically you can open it (the class; and add your method) anywhere. I usually make a special file called monkey_patches.rb and put it in config/initializers or in a misc folder in my Rails app so if theres ever a conflict I know where to look.

Also I'd advise to use a Module to wrap the monkey patch. Check out 3 ways to monkey patch without making a mess for more info.

His example:

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

DateTime.include CoreExtensions::DateTime::BusinessDays
like image 129
virtuexru Avatar answered Oct 01 '22 11:10

virtuexru


I have used the following technique described by Justin Weiss in 3 Ways to Monkey-Patch Without Making a Mess

When in vanilla Ruby, a gem, for instance, you define a module in some file you are requiring and then include (or extend) the module into desired class.

module StringMonkeypatch
  def foo
    #your special code 
  end
end

String.include StringMonkeypatch

When in Rails you may want to define the module in a place that gets autoloaded (look up autoload_paths) and in a way that follows Rails' naming convention.

For example, if monkeypatching the Sidekiq::Testing gem class you should mirror the file structure.

# 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
like image 44
Epigene Avatar answered Oct 01 '22 11:10

Epigene