En general, un módulo nunca puede sustituir un método en la clase está incluido en. Esto se debe a la inclusión del módulo funciona como subclases. Una superclase tampoco puede anular los métodos de las subclases , ni lo esperaría.
Cuando se incluye un módulo en una clase, el módulo se inserta justo después de la clase en la cadena de antepasados de la clase. Llamando super
de la clase llamará a la implementación del módulo .
class Something
module PreExtension; end
module PostExtension; end
include PreExtension
include PostExtension
end
Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
Cada vez que un método es llamado en un Something
, Ruby se ve a través esta lista en orden y llama a la primera aplicación que encuentra. Si la implementación llama al super
, sigue buscando y encuentra el siguiente.
Esto significa que los módulos incluyen más adelante tener prioridad sobre módulos incluidos anteriormente, y pueden llamar super
para obtener implementaciones anteriores los módulos.Esto se debe a que los módulos incluidos son insertados en la cadena de antecesores directamente después de la clase. Este es cómo funciona el código de enrutamiento edgerunner mencionado. Ese código pone todo en módulos, así:
class SomethingNew
module Base
def my_method
puts "(A)"
end
end
module Extension
def my_method
puts "(B)"
super
end
end
include Base
include Extension
end
SomethingNew.new.my_method
# Output:
# >> (B)
# >> (A)
SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
Esta es la razón por alias_method_chain
existió en el primer lugar. Si poner el código base en un módulo no es una opción, no estoy seguro de cómo lograr el equivalente de alias_method_chain
.
¡Dulce! Gracias. He visto la mayoría de los Railscasts, pero aún no los había visto. – mikewilliamson
Hack muy inteligente, mucho mejor que usar el alias incorporado del langage también ... – Oct
No creo que sea correcto. Según mi comprensión y este experimento, los métodos de los módulos nunca se llaman: https://gist.github.com/664352 – Peeja