Pregunta

¿Cómo es que Ruby permite a una clase acceder a métodos fuera de la clase implícitamente?

Ejemplo:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello
¿Fue útil?

Solución

La definición del '' jonrón '' El método es agregar el método a la clase Object. No está definiendo una función libre.

Class Candy hereda implícitamente de Object y, por lo tanto, tiene acceso a los métodos de Object. Cuando llamas a "homer" en la "tierra" método, la resolución del método no puede encontrar una definición en la clase actual, va a la superclase, encuentra el método que ha agregado a Object y lo llama.

Otros consejos

Una forma sencilla de descubrir qué sucede

  1. ¿Qué clases / módulos se buscan para resolver los métodos utilizados en los objetos Candy?

    p Candy.ancestors # = > [Dulces, Objetos, Kernel]

  2. ¿Candy tiene un método llamado jonrón?

    p Candy.instance_methods (false) .grep (" homer ") # = > []

    p Candy.private_instance_methods (false) .grep (" homer ") # = > []

  3. Bien, Candy no tiene ningún método llamado 'homer'.

  4. ¿Qué sigue en la cadena de búsqueda (ver 1) = > " Objeto "

  5. ¿Tiene el objeto un método llamado " homer " ?    p Object.instance_methods (false) .grep (" homer ") # = > []

    p Object.private_instance_methods (false) .grep (" homer ") # = > [" homer "]

Candy tiene Object en su cadena de búsqueda, que a su vez tiene un método de instancia privada " homer " para que la resolución del método sea satisfactoria

La declaración de definición siempre define el método en la clase de lo que self esté en el punto de definición

  1. ¿Qué es self justo antes de definir el homer?

    p self # = > principal   def jonrón     pone " Hola "   fin

  2. Entonces, ¿cuál es su tipo?

    p self.class # = > Objeto

Por eso homer termina en Object

Técnicamente, la definición del método homer está realmente en el módulo Kernel que se mezcla en Object , no en < código> Objeto directamente. Entonces, cuando homer no es una variable local o un método de instancia definido en Candy , la cadena de herencia del método Ruby se sigue a través de Object y luego a se ejecuta el módulo Kernel y luego se ejecuta este código.

Editar: Lo siento, no sé por qué pensé esto. Parece que el método realmente vive en Object . No estoy seguro de que haya una gran diferencia en la práctica, pero debería haber confirmado las cosas antes de publicar.

Ruby no tiene funciones de flotación libre. Cada método pertenece a algún objeto. Los métodos que def en el nivel superior se están convirtiendo en métodos de instancia de la clase Object . Como todo es un Object en algún nivel, todos los objetos tienen acceso a los métodos de instancia de Object .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top