Cosa fa l'operatore (unario) * in questo codice Ruby?


174

Dato il codice Ruby

line = "first_name=mickey;last_name=mouse;country=usa" 
record = Hash[*line.split(/=|;/)] 

Capisco tutto nella seconda riga a parte l' *operatore: cosa sta facendo e dov'è la documentazione per questo? (come puoi immaginare, la ricerca di questo caso si sta rivelando difficile ...)

Risposte:


271

Il *è il simbolo dell'operatore.

Si espande Arrayin un elenco di argomenti, in questo caso un elenco di argomenti per il Hash.[]metodo. (Per essere più precisi, espande qualsiasi oggetto che risponda a to_ary/ to_ao to_ain Ruby 1.9.)

Per illustrare, le seguenti due affermazioni sono uguali:

method arg1, arg2, arg3
method *[arg1, arg2, arg3]

Può anche essere utilizzato in un contesto diverso, per catturare tutti gli argomenti di metodo rimanenti in una definizione di metodo. In tal caso, non si espande, ma combina:

def method2(*args)  # args will hold Array of all arguments
end

Alcune informazioni più dettagliate qui .


36
In generale, quando utilizzato come in una situazione simile a LHS (ogni volta che lo si sta invocando su un valore), splat divide un array in valori separati e quando viene utilizzato in una situazione simile a RHS (ogni volta che lo si utilizza su alcune variabili precedentemente non definite), raggruppa valori separati in un array. Quindi a,b,*c = d,e,f,*gimposta a = d, b = e e c = [f, g0, g1, g2, ..., gn], dove g = [g0, g1, g2, ..., gn]
rampion

2
Solo per completezza, l'operatore splat trasforma una matrice in una lista nuda secondo la terminologia usata in "The Well Grounded Rubyist" di David A. Black
David Burrows,

12
@rampion: commento meraviglioso, hai appena mescolato LHS e RHS. È il contrario.
ThomasH,

46

L'operatore splat decomprime un array passato a una funzione in modo che ciascun elemento venga inviato alla funzione come singolo parametro.

Un semplice esempio:

>> def func(a, b, c)
>>   puts a, b, c
>> end
=> nil

>> func(1, 2, 3)  #we can call func with three parameters
1
2
3
=> nil

>> list = [1, 2, 3]
=> [1, 2, 3]

>> func(list) #We CAN'T call func with an array, even though it has three objects
ArgumentError: wrong number of arguments (1 for 3)
    from (irb):12:in 'func'
    from (irb):12

>> func(*list) #But we CAN call func with an unpacked array.
1
2
3
=> nil

Questo è tutto!


6

Come menzionano tutti, è uno "splat". Cercare la sintassi di Ruby è impossibile e l'ho posto in altre domande. La risposta a quella parte della domanda è che cerchi

asterisk in ruby syntax

in Google. Google è lì per te, basta esprimere ciò che vedi in parole.

Qualunque utente, come un sacco di codice Ruby, quel codice è piuttosto denso. Il

line.split(/=|;/)

rende un array di elementi SEI, first_name, mickey, last_name, mouse, country, usa. Quindi lo splat viene usato per trasformarlo in un hash. Ora le persone di Ruby ti inviano sempre a guardare il metodo Splat, poiché tutto è esposto in Ruby. Non ho idea di dove sia, ma una volta che lo avrai, vedrai che passa forattraverso l'array e crea l'hash.

Dovresti cercare il codice nella documentazione di base . Se non riesci a trovarlo (non potrei), proveresti a scrivere un codice come questo (che funziona, ma NON è un codice simile a Ruby):

line = "first_name=mickey;last_name=mouse;country=usa"
presplat = line.split(/=|;/)
splat = Hash.new
for i in (0..presplat.length-1)
    splat[presplat[i]] = presplat[i+1] if i%2==0
end

puts splat["first_name"]

e poi la banda di Ruby sarà in grado di dirti perché il tuo codice è sciocco, cattivo o semplicemente sbagliato.

Se hai letto fino a questo punto, leggi la documentazione di Hash per l'inizializzazione.

Fondamentalmente un hash inizializzato con diversi argomenti li crea come coppie chiave-valore:

Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}

Quindi nel tuo esempio questo porterebbe al seguente hash:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.