2009-08-07 13 views
21

Tengo un par de preguntas sobre los métodos, procedimientos y bloques de Ruby que me parecen bastante extrañas. No se trata tanto de sintaxis ni de función como la lógica detrás de las decisiones tomadas.Método de Ruby, Proc y confusión de bloques

Pregunta 1:

Por qué es que los bloques se puede pasar a métodos (por ejemplo cada uno) pero no se puede asignar a una variable?

Sé que puede pasarlos por alto en los procedimientos, es decir, p = Proc.new {...} (se accede con &p), pero no tiene mucho sentido hacer que el programador realice estos procedimientos.

Pregunta 2:

¿Por qué existe una diferenciación entre los métodos y procedimientos?

Por ejemplo, puedo lograr la tarea de definir una función y llamar a esa función en las dos formas siguientes:

def square(x) 
    x**2 
end 

square(3) 
=> 9 

o

square = lambda {|x| x**2} 
square.call(3) 
=> 9 

Por qué la diferenciación? En Python, por ejemplo, tanto la definición de una función de la manera estándar y por square = lambda x: x**2 realizan la misma tarea de crear la función y asignarla a square.

Respuesta

20

Pregunta 1: Los bloques no son objetos, son estructuras sintácticas; esta es la razón por la cual no pueden asignarse a una variable. Este es un privilegio reservado para objetos.

Pregunta 2: Los métodos no son objetos, por lo que no pueden recibir mensajes. Inversamente, procs y lambdas son objetos, por lo que no se pueden invocar como métodos, pero deben recibir un mensaje que les indique que devuelvan un valor en función de los parámetros que se pasaron con el mensaje.

Procs y Lambdas son objetos, por lo que pueden recibir el mensaje call y asignarse a los nombres. Para resumir, está siendo un objeto que hace que los procs y lambdas se comporten de forma extraña. Los métodos y bloques no son objetos y no comparten ese comportamiento.

+5

Rubí afirma que todo es un objeto. Los bloques deben ser objetos para ajustarse a eso, y se pueden pasar como argumentos, por lo que definitivamente actúan como objetos de alguna manera. – rpjohnst

+6

Se puede hacer que los bloques actúen como objetos mediante la creación de un objeto para representarlos, un proceso o una lambda. Sin ese dispositivo, son solo estructuras sintácticas. – Pinochle

+0

Hay objetos de bloque: ese es el propósito de lambda {whatever}. – Chuck

4

Los métodos son métodos, es decir, son acciones que un objeto puede realizar en respuesta a los mensajes. No son funciones.

Los bloques son cierres, son funciones que se cierran sobre el alcance adjunto. No "pertenecen" conceptualmente a un objeto dado.

En algunos idiomas, los métodos son simplemente funciones que son miembros de un objeto, pero Ruby no las ve de esta manera. Separar un método de su objeto de propiedad es más parecido a una cirugía que a una asignación simple. Ruby toma su modelo de orientación a objetos de Smalltalk, el abuelo del OO moderno.

5

En cierta medida, al menos, los métodos son objetos:

class ABC 
    def some_method 
    end 
end 
ABC.instance_method(:some_method) #=> #<UnboundMethod: ABC#some_method> 

Además de eso, hay una clase incorporada: Método, tal como se documenta here.

Ver también esto: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

azar <bseg>, parece más bien a confirmar el todo-es-un-objeto cosa. En este caso particular, parece que necesita un poco más de excavación para ver.

(tengo más remedio que hacer un esfuerzo para entender esto mejor: estoy empezando a pensar que es fundamental para conseguir una comprensión más profunda.)

+0

Los métodos parecen tomar su objetividad como instancias de 'Proc'. En la documentación 'ri' para' Método', la palabra 'método' no se usa en la explicación, pero 'proc' sí lo es. Las dos clases reciben los mismos mensajes, pero la diferencia es cómo se invocan y en el hecho de que los métodos se definen dentro del espacio de nombres de otro objeto, donde los procesos necesitan recibir el método 'call' para ser invocado y existir (persistir, como Dije antes) independientemente de otros objetos. – Pinochle

+0

Ahh, otra diferencia ... 'Method' no recibe el mensaje' new', donde 'Proc' sí. Si los métodos son objetos, no son objetos en un sentido completo (significado "completo" que tiene todas las características que estamos acostumbrados a ver en los objetos). – Pinochle

+0

Ese enlace de wikibooks es útil. Gracias. – David

Cuestiones relacionadas