No estoy seguro de si así es como el analizador de ruby realmente funciona, pero lo pienso de esta manera: La coma antes de delivery_confirm_path
tiene mayor precedencia que los paréntesis, a menos que se deshaga del espacio.
que el intérprete ve la llamada al método como este:
button_to "Confirm delivery", delivery_confirm_path
En otras palabras, delivery_confirm_path
se analiza como una llamada de método sin argumentos. Pero luego el analizador ve el (@delivery)
colgando y no es una sintaxis válida porque sigue la llamada al método button_to
. Es como si tuvieras esta sintaxis no válida:
button_to("Confirm delivery", delivery_confirm_path) (@delivery)
puede evitar el comas precedencia al hacer esto en su lugar:
button_to "Confirm delivery", (delivery_confirm_path (@delivery))
Pero por lo general es más fácil de quitar sólo el espacio.
El principio para recordar es que si hay un espacio antes de paréntesis con una llamada a un método, los paréntesis se utilizan como agrupación y no como paréntesis de llamada a método.
Aquí hay algunos ejemplos para ayudar. Yo uso el siguiente método en mis ejemplos:
def foo(*args); puts args.inspect; true; end
Si estás en Ruby 1.9, sugiero encender las advertencias cuando se ejecutan los ejemplos: $-w = true
. Esto mostrará warning: (...) interpreted as grouped expression
si tiene espacio antes de paréntesis.
Estas dos líneas son sintácticamente equivalentes:
foo (1)
foo 1
Eso es porque (1)
como una expresión agrupado es sólo 1
.
¿De qué sirve la agrupación?
Una razón es solo para una mayor legibilidad. Puede considerar que es más fácil de entender con parens en esta expresión que sin:
foo (2 + 3)
foo 2 + 3
Otro motivo es la precedencia. Supongamos que tengo una operación de baja precedencia, como el operador and
. Debido a que la llamada al método tiene una mayor prioridad, el and
se evalúa después de la llamada. Esto imprime [2]
y devuelve 3
:
foo 2 and 3 # same as foo(2) and 3, i.e. true and 3
Pero esto imprime [3]
y devuelve true
:
foo (2 and 3) # the grouped expr returns 3, which is passed to foo
Tenga en cuenta, sin embargo, que el ejemplo and
es un tanto artificial, porque rubí no permite la eliminación de los anteriores espacio. (No estoy seguro de por qué, ya que &&
está permitido en lugar de and
). Pero se entiende la idea.
foo(2 and 3) # syntax error - but why?? I still don't understand.
foo(2 && 3) # works fine. This is strangely inconsistent.
Esto demuestra que la eliminación del espacio antes de una llamada al método elevará la precedencia método de guardia por encima de una coma:
foo 1, foo 2 # syntax error; the 2 is dangling
foo 1, foo(2) # ok
Otra Gotcha es la lista de argumentos.
foo 2, 3 # both are treated as args to the method call
foo (2, 3) # syntax error, because "2, 3" is grouped as an expression, but is not a valid one
http://www.justskins.com/forums/ruby-1-8-space-122361.html – Gazler
parece como una limitación de la lengua. Encontraste una solución alternativa, no veo por qué tienes que ponerlo como una pregunta. – Candide
@Gazler +1, excelente enlace con una publicación del propio Matz! –