2010-06-06 18 views
11

¿Qué significa bloquear en Ruby? Se parece a Smalltalk, pero no puedes enviarle mensajes.Bloque en Ruby en comparación con Smalltalk

Por ejemplo, en Smalltalk:

[:x | x + 3] value: 3 

rendimientos 6. Pero en rubí:

{|x| x + 3}.call 3 

originen SyntaxError.

Bueno, puede pasar mensajes a lambda en rubí, sin embargo:

irb(main):025:0> ->(x){x+3}.call 3 
=> 6 

Así que en Ruby, el bloque no es un bloque, pero Lambda es un bloque? ¿Es esto cierto? Quiero decir, ¿hay alguna diferencia entre ruby ​​lambda y smalltalk block? Si esto es cierto, entonces, ¿qué es un bloque de rubíes?

Actualización:

Desde el comentario y responder a continuación, junto con algunas google, supongo que más entendimiento del bloque Ruby. En Ruby, generalmente una pieza de código evalúa un valor, y cada valor es un objeto. Pero, bloque no evalúa un valor. Entonces no es un objeto En cambio, puede actuar como parte de un objeto. Por ejemplo, en {| x | x + 3} puede actuar como una parte del objeto proc {| x | x + 3}.

Pero me confundió. En smalltalk, casi todas las expresiones se pueden dividir en objetos (el enlace a las variables son excepciones). Parece que en Ruby, hay más excepciones.

+0

Creo que te estás perdiendo un rendimiento. Aunque no soy muy experto en bloques ... – Earlz

+0

Gracias por señalar el rendimiento. Encontré esta pregunta relacionada: http://stackoverflow.com/questions/764134/rubys-yield-feature-in-relation-to-computer-science – weakish

Respuesta

14

Lo primero y más importante que el bloque Ruby no es: un objeto. Es una construcción sintáctica, y obviamente también tiene una implementación equivalente, pero no es un objeto y, por lo tanto, no puede recibir mensajes. Lo que hace que su ejemplo de

{|x| x + 3}.call 3 

ungrammatical. Lambdas, procs: son objetos que envuelven un bloque y tienen un método call que ejecuta el bloque.

Por lo tanto, un bloque es simplemente una pieza de código que se puede pasar a un método, fuera de la lista de argumentos, ni más ni menos. Si se le pasa a Proc.new constructor, por ejemplo, se envuelve y te dará un objeto que puede manejar:

Proc.new {|x| x + 3}.call 3 
+0

Pensé erróneamente que el bloque Ruby es un objeto que pasamos al método como su argumento. Gracias por aclararlo. – weakish

+0

Entonces, si lo entiendo correctamente, también significa que cuando pasa un bloque de ruby ​​como parámetro a un método, la máquina virtual de alguna manera lo envuelve en un Proc.new? – mathk

+0

No conozco las entrañas, pero creo que es incorrecto, a menos que lo haga con la marca '&'. Bloque implícito (sin envoltura): 'def yield3; rendimiento 3; fin; yield3() {| x | puts x}; '- Proc explícito (no se pasa el bloque):' def callprocwith3 (func); func.call (3); fin; callprocwith3 (Proc.new {| x | puts x}) '- Convertido a proc (envolviendo un bloque):' def callblockwith3 (&func); func.call (3); end; callblockwith3() {| x | puts x}; ' - todos hacen más o menos lo mismo, pero la forma en que lo manejas es diferente. Pude haber dejado los pares vacíos '()', pero de esta manera está más claro qué es un argumento y qué no. – Amadan

1

Una precisión:

incluso diría que incluso en Smalltalk es vinculante hecho con objeto. Piensa en el MethodContext. Lo que realmente está haciendo es almacenar el objeto en MethodContext. Así

a := Object new 

Se puede grabar en:

thisContext at: 1 put: Object new. 

Pero obviamente usted no escribir de esta manera ya que se necesita saber De donde es la variable temps.

1

Un bloque en Smalltalk es un objeto anónimo. Sintácticamente, está delimitado por un [ ... ] par.

Cuando se evalúa, devolverá la última expresión evaluada en sí misma, y ​​hay muchos métodos en su protocolo.

Éstos son los comentarios de clase para Bloques de Smalltalk (en este caso, Dolphin Smalltalk 6,03 Community Edition)

"Bloques encapsular una secuencia de instrucciones que se deben realizar en un momento posterior. Los bloques pueden capturar (o "close over") estado de tiempo de ejecución, como los valores de las variables temporales, del alcance léxico adjunto en el punto donde se crean. Cuando se evalúa, un bloque se ejecuta como en el ámbito léxico en el que se definió, excepto que bloquea puede tener argumentos que están vinculados en el momento de la evaluación. Los bloques se pueden pasar como argumentos con mensajes a otros objetos y evaluados por esos objetos cuando corresponda, y así formar un mecanismo de "conectabilidad" muy poderoso y genérico. anismo que es una característica central que proporciona gran parte del poder de Smalltalk ".

Por el contrario, un bloque en Ruby es simplemente una cadena de parámetros. Está delimitado sintácticamente por un par { ... }, pero no tiene sus propios métodos.

Cuestiones relacionadas