2012-07-09 12 views
18

No entiendo por qué funciona esto.Ruby: módulos y super?

module Base 
    attr_reader :first 
    def setup 
    @first = 1 
    end 
end 

module Addon 
    attr_reader :second 
    def setup 
    #super 
    @second = 2 
    end 
end 

class Test 
    include Base 
    include Addon 

    def initialize(num) 
    @num = num 
    setup 
    end 
end 

a = Test.new(1) 
p a.first 
p a.second 

Básicamente tengo un módulo "base", que configura algunas cosas. También tengo un módulo de complemento, que establece algunas cosas más si alguna clase quiere incluirlo.

Ahora en que probarlo, si yo no tengo esa llamada súper, consigo

nil 
2 

Cuando tengo la llamada súper, consigo

1 
2 

Lo que hace realmente súper hacer aquí? Llama al método de configuración desde el módulo Base, incluso cuando Base y Addon no están relacionados.

Esta es la primera vez que utilizo Super en el contexto de los módulos. Anteriormente siempre usaba superdesplazamientos con clases y pensaba que solo estaba subiendo en el árbol de herencia para buscar un padre con el mismo método.

¿Incluye varios módulos que también configuran algún tipo de árbol de herencia?

EDITAR: para el contexto, el módulo Complemento nunca se incluirá sin el módulo Base, y el módulo Base siempre se incluirá antes de cualquier módulo Complemento adicional.

+0

Creo que tienes razón. Las firmas de método probablemente se almacenan en una pila y Super simplemente envía el mensaje al objeto más profundo en la pila. ¡Interesante hallazgo diría! – Candide

Respuesta

23

Sí, cuando se incluye módulos, que se inyectan en cadena de herencia módulo

Test.ancestors # => [Test, Addon, Base, Object, Kernel, BasicObject] 

Addon, cuando se incluye, redefine existente setup método de Base. Si quiere que se llame a la Base, use super.