2012-05-21 8 views
7

Soy nuevo en Ruby. Estoy familiarizado con varios otros idiomas. Mi pregunta es acerca de llamar métodos fuera de servicio. Por ejemplo:¿Cómo manejar el orden de los métodos en Ruby?

def myfunction 
    myfunction2 
end 

def myfunction2 
    puts "in 2" 
end 

¿Cómo podría llamar MyFunction2 antes de que se declara? Varios idiomas le permiten declararlo en la parte superior o en un archivo .h. ¿Cómo lo maneja Ruby?

qué siempre es necesario seguir este:

def myfunction2 
    puts "in 2" 
end 

def myfunction 
    myfunction2 
end 

Principalmente esto me molesta cuando tengo que llamar a otro método en el interior de def initialize para una clase.

Respuesta

18

No puede llamar a un método antes de definirlo. Sin embargo, eso no significa que no pueda definir myfunction antes de myfunction2!Ruby tiene vinculación tardía, por lo que la llamada a myfunction2 en myfunction no se asociará con el myfunction2 real antes de llamar al myfunction. Eso significa que siempre que se realice la primera llamada a myfunctiondespués de que se haya declaradomyfunction2, debería estar bien.

Por lo tanto, esto está bien:

def myfunction 
    myfunction2 
end 

def myfunction2 
    puts "in 2" 
end 

myfunction 

y esto no es:

def myfunction 
    myfunction2 
end 

myfunction 

def myfunction2 
    puts "in 2" 
end 
+2

Nota el ejemplo que no funciona se puede martillar en el código de trabajo mediante la adición de una declaración 'BEGIN': 'BEGIN {def myfunction2; pone "en 2"; end} '. – steenslag

+2

@steenslag Un enfoque aún mejor sería agregar una declaración 'END':' END {myfunction} '. –

-1

Puede definir el método en cualquier orden, el orden no importa nada.

1

Rubí se interpreta el lenguaje por lo que no dependen de la orden de funciones, ejemplo:

[1] pry(main)> def myfunction 
[1] pry(main)* myfunction2  
[1] pry(main)* end 
=> nil 
[2] pry(main)> 
[3] pry(main)> def myfunction2 
[3] pry(main)* puts "in 2"  
[3] pry(main)* end 
=> nil 
[4] pry(main)> myfunction 
in 2 
=> nil 

También si, por ejemplo, la función llama a la función no existente, entonces excepción de ejecución será llamado sólo si esa función se ser llamado, i. E .:

[5] pry(main)> def foo 
[5] pry(main)* blubry_starego_marycha 
[5] pry(main)* end 
=> nil 
[6] pry(main)> def boo 
[6] pry(main)* "bom bom bom" 
[6] pry(main)* end 
=> nil 
[7] pry(main)> boo 
=> "bom bom bom" 
[8] pry(main)> foo 
NameError: undefined local variable or method `blubry_starego_marycha' for main:Object 
from (pry):9:in `foo' 

Como se puede ver la función foo que llama a la función inexistente blubry_starego_marycha y Ruby es muy bien con él he declarado, es elevar excepción sólo si llamo foo.

7

Las únicas cuestiones de orden método de tiempo está en el código de mero trámite, y eso es por lo general miope, dado dos métodos:

def greet 
    puts "%s, Dave" % random_greeting 
end 
# If I try to use `greet` here, it'll raise a NoMethodError 
def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
end 
# I can use `greet` here, because `random_greeting` is now defiend 

Esto funcionaría bien, a menos que quiera utilizar greet antes random_greeting se define, la forma en que todo el código no trivial resuelve este es envolver el comportamiento en una clase:

class Doorman 
    def greet 
    puts "%s, Dave" % random_greeting 
    end 
    def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
    end 
end 
Doorman.new.greet 

uno puede entonces recibir a los huéspedes de uno con Doorman.new.greet, envolviendo el comportamiento en una clase se puede modelar la aplicación Bett er (tal vez diferentes objetos en su Código de hotel dar diferentes saludos, por ejemplo) y también mantiene el main namespace clean.

El objeto main en Ruby ya tiene 114 métodos definidos, por lo que es mucho mejor poner sus propios métodos en clases que representen actores u objetos en el modelo de su proyecto.

Además de lo que ha dicho en la pregunta sobre de inicialización de una clase, esto es totalmente posible:

class Doorman 
    def initialize 
    puts "%s, I'm a new Doorman instance" & random_greeting 
    end 
    def greet 
    "%s, Dave" % random_greeting 
    end 
    def random_greeting 
    ["Hello", "Bonjour", "Hallo"].sample 
    end 
end 

A pesar de que el método random_greeting no está definida cuando escribimos initailize, el conjunto de clases se define antes de llamar al initialize. De nuevo, al envolver las clases, esto hace la vida más fácil, más limpia y significa que las cosas permanecen en encapsulated.

Cuestiones relacionadas