Posted over 3 years ago. Visible to the public. Repeats.

Ruby: How to use prepend for cleaner monkey patches

Let's say you have a gem which has the following module:

Copy
module SuperClient def self.foo 'Foo' end def bar 'Bar' end end

For reasons you need to override foo and bar.

Keep in mind: Your code quality is getting worse with with each prepend (other developers are not happy to find many library extensions). Try to avoid it if possible.

  1. Add a lib/ext/super_client.rb to your project (see How to organize monkey patches in Ruby on Rails projects)
  2. Add the extension, which overrides both methods (prepend is available since Ruby >=2)
Copy
module SuperClientExtension def self.prepended(base) base.singleton_class.send(:prepend, ClassMethods) end module ClassMethods def foo 'New foo' end end def bar 'New bar' end end module SuperClient prepend SuperClientExtension end

Test

Copy
class Test; include SuperClient; end Test.foo => 'New foo' Test.new.bar => 'New bar'

Good practice

If you do monkey patches, you could raise if the version you monkey patched changes. So that someone who does an update will be notified and can check if the monkey patch is still necessary.

Why you should do it this way (instead of doing regular monkey patches)

  • you can still call super to get the original implementation of the method
  • the prepended class will appear in the list of ancestors

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Emanuel De
Last edit:
11 days ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Emanuel De to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more