Domanda

NOTA: Mischa's Splat su github Ha molti esempi interattivi fantastici di * in azione.

In Google, ho scoperto che un modo per iterare su una serie di numeri in Ruby (il tuo classico stile C per loop)

for (i = first; i <= last; i++) {
  whatever(i);
}

è fare qualcosa del genere

[*first..last].each do |i|
  whatever i
end

Ma cosa sta succedendo esattamente con quello [*first..last] sintassi? Ho giocato in giro con irb E vedo questo:

ruby-1.9.2-p180 :001 > 0..5
 => 0..5 
ruby-1.9.2-p180 :002 > [0..5]
 => [0..5] 
ruby-1.9.2-p180 :003 > [*0..5]
 => [0, 1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :004 > *0..5
SyntaxError: (irb):4: syntax error, unexpected tDOT2, expecting tCOLON2 or '[' or '.'
*0..5
    ^

Tutto ciò che ho letto online discute l'asterisco unario come utile per l'espansione e il collasso degli argomenti passati a un metodo, utile per elenchi di argomenti di lunghezza variabile

def foo(*bar)
  bar 
end

foo 'tater' # => ["tater"]
foo 'tater', 'tot' # => ["tater", "tot"]

E lo capisco, ma non vedo come si applica all'espansione fatta nel mio blocco sopra.

Per essere chiari, so che il Ruby Way è di iterare su un array o una raccolta, non usare la lunghezza dell'array e iterare con un indice intero. Tuttavia, in questo esempio, ho davvero a che fare con un elenco di numeri interi. :)

È stato utile?

Soluzione

[*1..10]

è la stessa cosa di

(1..10).to_a # call the "to array" method

Istanze del Array classe hai creato implement Enumerable Quindi il tuo loop funziona. Su classi che definiscono a to_a metodo, puoi usare il operatore splat sintassi con parentesi. Splat fa molto di più che chiamare #to_a Tuttavia, varrebbe una ricerca su Google da solo.

Ora, nel tuo caso, il Range La classe stessa è già un Enumerable Quindi potresti solo fare:

(first..last).each do |v| 
  ...
end

Altri suggerimenti

[first..last] è un array contenente solo 1 oggetto di portata. [*first..last] è un array contenente gli elementi di quell'intervallo che sono stati inviati come elenco di argomenti. * funziona nel contesto di un elenco di argomenti.

Si chiama operatore splat. Se lo usi all'interno di determinate posizioni come una posizione di argomento o un array, si espanderà nei suoi elementi:

a = [1]
[*a, 3] # => [1, 3]
b = [1, 2]
[*b, 3] # => [1, 2, 3]

Non puoi usarlo nudo o in gamme:

*a..3 # => error.
(*a..3) # => error.

Quando hai qualcosa che non è un array, torna da solo:

a = 1
[*a, 3] # => [1, 3]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top