Your question led me to this interesting article that describes the problem:
Fixing an inheritance model in Rubys with a metamorph
This is the final problem with the Rubys inheritance model, in my opinion. Since mixins always take a lower priority than methods defined directly in the class, A # foo cannot be overridden by the inclusion of mixin. Moreover, since mixins take a lower priority than methods, A # foo now breaks encapsulation [...]
And his solution is to transparently define all new methods inside an anonymous internal module:
class Object def self.method_added(name) return if name == :initialize const_set(:InstanceMethods, Module.new) unless defined?(self::InstanceMethods) meth = instance_method(name) self::InstanceMethods.send(:define_method, name) {|*args, &block| meth.bind(self).call(*args, &block) } remove_method(name) include self::InstanceMethods end end
It is also conveniently packaged in a library called metamorph , which allows you to use mixin methods to override class methods, just requiring it.
source share