Dove è legale utilizzare l’operatore di ruby ​​splat?

Gli splats sono fantastici. Non sono solo per gli array che esplodono, anche se è divertente. Possono anche eseguire il cast su Array e appiattire gli array (vedere http://github.com/mischa/splat/tree/master per un elenco completo di ciò che fanno).

Sembra che non sia ansible eseguire operazioni aggiuntive sullo splat, ma in 1.8.6 / 1.9 il seguente codice genera “tSTAR inatteso”:

foo = bar || *zap #=> unexpected tSTAR

Mentre questo funziona:

foo = *zap || bar #=> works, but of limited value

Dove può apparire lo splat in un’espressione?

Innanzitutto, la precedenza non è un problema qui, perché foo = bar || (*zap) foo = bar || (*zap) non funziona meglio. La regola generale è che non è ansible eseguire operazioni aggiuntive su uno splat. Anche qualcosa di semplice come foo = (*zap) non è valido. Questo vale anche per 1.9.

Detto questo, cosa ti aspetti foo = bar || *zap foo = bar || *zap da fare, se ha funzionato, è diverso da foo = bar || zap foo = bar || zap ? Anche in un caso come a, b = bar || *zap a, b = bar || *zap (che inoltre non funziona), a, b = bar || zap a, b = bar || zap realizza ciò che suppongo sarebbe la stessa cosa.

L’unica situazione in cui ciò potrebbe avere senso è qualcosa come a, b = foo, bar || *zap a, b = foo, bar || *zap . Dovresti scoprire che la maggior parte dei casi in cui vorresti utilizzarli sono coperti da a, b = foo, *(bar || zap) . Se questo non copre il tuo caso, probabilmente dovresti chiederti cosa speri davvero di realizzare scrivendo un costrutto così brutto.


MODIFICARE:

In risposta ai tuoi commenti, *zap || bar *zap || bar è equivalente a *(zap || bar) . Questo dimostra quanto sia bassa la precedenza dello splat. Esattamente quanto è basso? La migliore risposta che posso darti è “piuttosto bassa”.

Per un esempio interessante, però, considera un metodo foo che prende tre argomenti:

 def foo(a, b, c) #important stuff happens here! end 

foo(*bar = [1, 2, 3]) si splatter dopo l’assegnazione e imposta gli argomenti rispettivamente su 1, 2 e 3. Confrontalo con foo((*bar = [1, 2, 3])) che si lamenterà di avere il numero sbagliato di argomenti (1 per 3).

L’operatore di “splat” in realtà non è un operatore ma un token definito nella grammatica di Ruby. Una lettura attraverso grammar.y o la grammatica di Ruby in forma BNF * ti dirà che è permesso come ultimo o unico argomento:

  • in una definizione di metodo (eccetto per un ultimo &foo opzionale)
  • in una chiamata al metodo (eccetto per un ultimo &foo )
  • sul LHS di incarico, ad esempio: a, b, *cs = [1,2,3,4]
  • sull’RHS di un incarico, ad esempio: a, b, c = 1, 2, *[3,4,5]
  • nella clausola when di una dichiarazione di un caso