Mientras parcheamos un módulo de un motor de Rails, descubrimos que si antepone un módulo B a otro módulo A, el módulo B antepuesto no se agregará a los ancestros de las clases que ya incluyeron el módulo A antes de prepend . Para ilustrar:
module A def a puts 'a' end end class B include A end module C def a puts 'c' end A.prepend self end class D include A end B.new.a # prints: a D.new.a # prints: c B.ancestors #=> [B, A, Object, Kernel, BasicObject] D.ancestors #=> [D, C, A, Object, Kernel, BasicObject] Ambas clases, B y D , incluyen A , pero solo D toma el nuevo comportamiento, ya que es el que se define después de llamar a prepend .
Por el contrario, aprendimos que la herencia de clases no muestra este comportamiento:
class A def a puts 'a' end end class B < A end module C def a puts 'c' end A.prepend self end class D < A end B.new.a # prints: c D.new.a # prints: c B.ancestors #=> [B, C, A, Object, Kernel, BasicObject] D.ancestors #=> [D, C, A, Object, Kernel, BasicObject] Esta vez, ambas clases, B y D , han tomado el nuevo comportamiento, incluso si B se definió antes de llamar a prepend .
¿Hay alguna razón por la cual prepend se comporta de manera diferente cuando se usa con módulos versus clases? Supongo que esto es por diseño, pero presenta un problema cuando se usa prepend con módulos.
https://bugs.ruby-lang.org/issues/9573 muestra un comportamiento similar en cuanto a clases y módulos. El informe de error se publicó en 2014 y solo se cerró en 2020. Según ese informe, confirmé manualmente que