We’ve been prepending classes a lot recently as a means of mokeypatching, but in a “nicer” way. Turns out you can do this with modules too.
Let’s say you’ve got a class in a gem somewhere and you want to override some of its behaviors.
module Roaring def roar "Roar!" end end class MythicalBeast include Roaring end
The default looks like:
class Dragon < MythicalBeast end
> Dragon.new.roar => "Roar!"
You can change that roar using
prepend. Typically, this involves changing the class:
module BetterRoar def roar "RRRROOOOOAAAARRRRRRRRR!!!!!!!" end end
> MythicalBeast.prepend BetterRoar > Dragon.new.roar => "RRRROOOOOAAAARRRRRRRRR!!!!!!!"
But, you can can also do this on the module:
> Roaring.prepend BetterRoar > Dragon.new.roar => "RRRROOOOOAAAARRRRRRRRR!!!!!!!"
The only different is that you’ll need to reload the classes, which Rails will do in the
the application config.
Why do this?
Well, it’s really up to you, but prepending the module instead of the class is a bit more
self-documenting because in your
config.to_prepare block you’d see something like:
config.to_preprae do Roaring.prepend BetterRoar end
This is a bit more explicit in the sense that it’s telling you where the original behavior exists that you’re changing. If you chose to prepend the class:
config.to_preprae do MythicalBeast.prepend BetterRoar end
You don’t know that the roar method really existing in the Roaring module.