Dove è legale usare ruby operatore splat?
-
13-09-2019 - |
Domanda
Simboli sono fresche. Non sono solo per esplodere gli array, anche se questo è divertente. Essi possono anche lanciare per Array e appiattire array (vedi http://github.com/mischa/splat/ albero / master per una lista esaustiva di quello che fanno.)
Sembra che non si può eseguire operazioni aggiuntive sulla tempra, ma in 1.8.6 / 1.9 il seguente codice getta "inaspettato Tstar":
foo = bar || *zap #=> unexpected tSTAR
considerando che questo funziona:
foo = *zap || bar #=> works, but of limited value
Dove è possibile la splat comparire in un'espressione?
Soluzione
In primo luogo, la priorità non è un problema qui, perché foo = bar || (*zap)
meglio funziona. La regola generale è che non è possibile eseguire operazioni aggiuntive su un simbolo. Anche qualcosa di semplice come foo = (*zap)
non è valido. Questo vale per 1.9 pure.
Detto questo, che cosa vi aspettate foo = bar || *zap
da fare, se ha funzionato, che è diverso da quello foo = bar || zap
? Anche in un caso come a, b = bar || *zap
(che pure non funziona), a, b = bar || zap
compie quello che piacerebbe pensare sarebbe la stessa cosa.
L'unica situazione in cui questo potrebbe avere un senso è qualcosa di simile a, b = foo, bar || *zap
. Si dovrebbe trovare che la maggior parte dei casi in cui si vorrebbe utilizzare questo sono coperti da a, b = foo, *(bar || zap)
. Se questo non copre il vostro caso, probabilmente si dovrebbe chiedersi cosa realmente sperate di ottenere scrivendo una tale brutta costrutto.
EDIT:
In risposta ai vostri commenti, *zap || bar
equivale a *(zap || bar)
. Questo dimostra quanto in basso la priorità del splat è. Esattamente quanto in basso è? La migliore risposta che posso darvi è "piuttosto basso".
Per un esempio interessante, però, si consideri un metodo foo
che prende tre parametri:
def foo(a, b, c)
#important stuff happens here!
end
foo(*bar = [1, 2, 3])
sarà splat dopo l'assegnazione e impostare gli argomenti per 1, 2, e 3 rispettivamente. Confronti che, con foo((*bar = [1, 2, 3]))
che lamentano di avere il numero sbagliato di argomenti (1 per 3).
Altri suggerimenti
L ' "operatore di splat" in realtà non è un operatore a tutti, ma un gettone definito nella grammatica Ruby. Una lettura attraverso grammar.y o la grammatica di Ruby in forma BNF * vi dirà che è consentito come l'ultimo o unico argomento:
- in una definizione di metodo (ad eccezione di un ultimo
&foo
opzionale) - in una chiamata di metodo (ad eccezione di un ultimo
&foo
opzionale) - sul lato sinistro di come l'assegnazione, ad esempio:
a, b, *cs = [1,2,3,4]
- sul RHS di un incarico, per esempio:
a, b, c = 1, 2, *[3,4,5]
- nella clausola in cui di un'istruzione case