Non sono sicuro se questo è il modo in cui il parser di Ruby funziona, ma penso in questo modo: La virgola prima dello delivery_confirm_path
ha precedenza più alta delle parentesi, a meno che non si liberi dello spazio.
Il parser vede la chiamata metodo come questo:
button_to "Confirm delivery", delivery_confirm_path
In altre parole, delivery_confirm_path
viene analizzato come una chiamata metodo senza argomenti. Ma poi il parser vede il penzoloni (@delivery)
e non è una sintassi valida perché segue la chiamata al metodo button_to
. E 'come se tu avessi questa sintassi non valida:
button_to("Confirm delivery", delivery_confirm_path) (@delivery)
si può evitare la virgola-la precedenza in questo modo invece:
button_to "Confirm delivery", (delivery_confirm_path (@delivery))
ma di solito è più facile da rimuovere solo lo spazio.
Il principio da ricordare è che se c'è uno spazio prima delle parentesi con una chiamata al metodo, le parentesi vengono utilizzate come raggruppamento, e non come parentesi chiamata a metodo.
Ecco alcuni esempi per aiutare. Io uso il seguente metodo nei miei esempi:
def foo(*args); puts args.inspect; true; end
Se siete su Ruby 1.9, ti suggerisco di accendere gli avvertimenti durante l'esecuzione degli esempi: $-w = true
. Questo mostrerà warning: (...) interpreted as grouped expression
se hai spazio prima delle parentesi.
Queste due linee sono sintatticamente equivalenti:
foo (1)
foo 1
Questo perché (1)
come espressione raggruppato è solo 1
.
A cosa serve raggruppare?
Una ragione è solo per una maggiore leggibilità. Potresti considerare più facile capire con paren- in questa espressione contro:
foo (2 + 3)
foo 2 + 3
Un'altra ragione è la precedenza. Diciamo che ho un'operazione di precedenza bassa, come l'operatore and
. Poiché la chiamata al metodo ha precedenza più elevata, lo and
viene valutato dopo la chiamata. Questo stampa [2]
e restituisce 3
:
foo 2 and 3 # same as foo(2) and 3, i.e. true and 3
Ma questa stampa [3]
e restituisce true
:
foo (2 and 3) # the grouped expr returns 3, which is passed to foo
Si noti tuttavia che l'esempio and
è un po 'artificiosa, perché rubino non consente la rimozione del precedente spazio. (Non sono sicuro del perché, dal momento che &&
è consentito invece di and
.) Ma tu hai l'idea.
foo(2 and 3) # syntax error - but why?? I still don't understand.
foo(2 && 3) # works fine. This is strangely inconsistent.
Questo dimostra che la rimozione lo spazio prima di una chiamata di metodo eleverà la precedenza metodo di chiamata sopra una virgola:
foo 1, foo 2 # syntax error; the 2 is dangling
foo 1, foo(2) # ok
Un altro punto è liste di argomenti.
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
Sembra come una limitazione della lingua. Hai trovato una soluzione alternativa, non vedo perché dovevi metterlo come domanda. – Candide
@Gazler +1, ottimo collegamento con un post dello stesso Matz! –