2011-05-30 18 views
9

nadie puede explicar por qué el siguiente código aborta con un errorDefinición de bloque: diferencia entre llaves y do-end?

irb(main):186:0> print ((1..10).collect do |x| x**2 end) 
SyntaxError: (irb):186: syntax error, unexpected keyword_do_block, 
expecting ')' 
print ((1..10).collect do |x| x**2 end) 
         ^
(irb):186: syntax error, unexpected keyword_end, expecting $end 
print ((1..10).collect do |x| x**2 end) 
            ^
     from /usr/bin/irb:12:in `<main>' 

Considerando que, tras código con las mismas obras de funcionalidad como se esperaba?

irb(main):187:0> print ((1..10).collect { |x| x**2 }) 
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]=> nil 

Yo creía entre llaves "{}" puede sustituir "terminan" arbitrariamente en el bloque definición.

sé que puedo "arreglar" la primera llamada al omitir un espacio entre la letra impresa método y el primer paréntesis, pero estoy interesado en una explicación por qué se comporta diferente.

+0

Ver [premisa de pregunta similar] (http://stackoverflow.com/questions/2122380/using-do-block-vs-brackets) también. – Zabba

+0

Este es un duplicado de [Ruby Block Syntax Error] (http://StackOverflow.Com/q/6854283/), [Code block pasado a 'each' funciona con paréntesis pero no con' do' -'end' (ruby)] (http://StackOverflow.Com/q/6718340/), [Ruby bloque multilínea sin 'do'' end'] (http://StackOverflow.Com/q/3680097/), [Usando el bloque 'do' vs corchetes '{}'] (http://StackOverflow.Com/q/2122380/), [¿Cuál es la diferencia o el valor de estos estilos de codificación de bloque en Ruby?] (http://StackOverflow.Com/q/533008 /) y [Ruby block y argumentos sin apariencia] (http://StackOverflow.Com/q/420147/). –

+0

@coreyward: ¿Y revertir? –

Respuesta

13

La diferencia es precedencia:

# Equivalent to puts((1..10).map { |i| i*2 }) 
> puts (1..10).map { |i| i*2 } 
2 
4 
6 
8 
10 
12 
14 
16 
18 
20 
=> nil 

# Equivalent to puts((1..10).map) { |i| i*2 } 
> puts (1..10).map do |i| i*2 end 
#<Enumerator:0x928f24> 
=> nil 

En el primer caso, el bloque se pasa a map, y todo funciona correctamente. En el segundo caso, el bloque se pasa al puts, que no hace nada con él. map no recibe un bloque y simplemente devuelve un enumerador.

En cuanto al error de sintaxis, si se quita el espacio entre print y ( todo funciona;)

La diferencia es si el rubí es el tratamiento de los paréntesis, como delimitadores argumento de método, o si se trata de una agrupación declaración genérica. No estoy seguro de la diferencia exacta, pero es sutil y molesto

+0

Su segundo ejemplo es diferente del que está en la pregunta. – sawa

+0

Sí, es solo una demostración de precedencia, no una solución directa. Lo siento si eso no estaba claro – Gareth

0

Hay un últimoanswer ya en SO.

Lamentablemente esto es definitivamente no una buena demostración de la filosofía menos sorpresa detrás de Ruby.

Cuestiones relacionadas