Rails: How to use prepend to avoid monkey patches in modules
Let's say you have a gem which has the following module:
Copymodule 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.
- Add a
lib/ext/super_client.rb
to your project (Folder or file needs to be required in an initializer) - Add the extension, which overrides both methods (prepend is available since ruby >=2)
Copymodule 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
Copyclass Test; include SuperClient; end SuperClient.foo => 'New foo' Test.new.bar => 'New bar'
By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.