Sometimes we’d like to monkey patch some classes/modules from external libraries for many reasons including bug fixes until a new library version is released or maybe we need to change the default behavior of some class. For instance, the active_record_migrations gem will allow migrations to be used as an independent project and it supports changing the default location for the migrations from “db/migrate” to something else. But “db/migrate” is hard coded in some method:
That means the only option for active_record_migrations is to
override “create_migration_file” by copying the original implementation and allowing the path to be customized: A bit ugly and fragile solution, I know, but I can’t think of another option since my PR has been ignored in the last months but it doesn’t matter for what I’m requesting. This is just an example to demonstrate that sometimes we’re forced to monkey patch some classes to support some features. For this particular case no monkey patch was required and inheritance was used instead but in other cases we don’t have this option. In such cases having something like Object#preextend could be helpful in how we manage such patches by isolating them in separate modules. Instead of reopening a class to change some class method we could add the alternative implementation in a separate module and call #preextend in a similar way we do with prepend. I’ve requested this feature to Ruby itself and Boris came with a simple enough implementation that maybe could be added to ActiveSupport if you agree: Suggested implementation by Boris Stitnicky: Pretty simple, right? module LibraryImpl def self.library_method ‘original impl’ end end module MyPatch def library_method original_impl = super “#{original_impl} => patched impl” end end LibraryImpl.preextend MyPatch assert LibraryImpl.library_method == ‘original impl => patched impl’ What do you think?