Was macht der (unäre) * Operator in diesem Ruby-Code?


174

Angesichts des Ruby-Codes

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

Ich verstehe alles in der zweiten Zeile außer dem *Operator - was macht es und wo ist die Dokumentation dafür? (Wie Sie vielleicht erraten haben, erweist sich die Suche nach diesem Fall als schwierig ...)

Antworten:


271

Das *ist der Splat- Operator.

Es erweitert a Arrayin eine Liste von Argumenten, in diesem Fall eine Liste von Argumenten für die Hash.[]Methode. (Genauer gesagt wird jedes Objekt erweitert, das auf to_ary/ to_aoder to_ain Ruby 1.9 reagiert .)

Zur Veranschaulichung sind die folgenden zwei Aussagen gleich:

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

Es kann auch in einem anderen Kontext verwendet werden, um alle verbleibenden Methodenargumente in einer Methodendefinition abzufangen. In diesem Fall wird es nicht erweitert, sondern kombiniert:

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

Einige detailliertere Informationen hier .


36
Im Allgemeinen teilt splat ein Array bei Verwendung wie in einer LHS-ähnlichen Situation (jedes Mal, wenn Sie es für einen Wert aufrufen) in separate Werte auf und bei Verwendung in einer RHS-ähnlichen Situation (jedes Mal, wenn Sie es verwenden) Bei einigen zuvor nicht definierten Variablen werden separate Werte in einem Array gruppiert. Also a,b,*c = d,e,f,*gsetzt a = d, b = e und c = [f, g0, g1, g2, ..., gn], wobei g = [g0, g1, g2, ..., gn]
Rampion

2
Der Vollständigkeit halber wandelt der Splat-Operator ein Array gemäß der in "The Well Grounded Rubyist" von David A. Black
David Burrows,

12
@rampion: Wundervoller Kommentar, du hast gerade LHS und RHS gemischt. Es ist umgekehrt.
ThomasH

46

Der splat-Operator entpackt ein an eine Funktion übergebenes Array, sodass jedes Element als einzelner Parameter an die Funktion gesendet wird.

Ein einfaches Beispiel:

>> 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

Das ist es!


6

Wie jeder erwähnt, ist es ein "Splat". Das Suchen nach Ruby-Syntax ist unmöglich, und ich habe dies in anderen Fragen gestellt. Die Antwort auf diesen Teil der Frage lautet, dass Sie weiter suchen

asterisk in ruby syntax

in Google. Google ist für Sie da, setzen Sie einfach das, was Sie sehen, in Worte.

Wie viel Ruby-Code ist dieser Code ziemlich dicht. Das

line.split(/=|;/)

macht ein Array von sechs Elementen , first_name, mickey, last_name, mouse, country, usa. Dann wird der Splat verwendet, um daraus einen Hash zu machen. Jetzt schicken Sie die Ruby-Leute immer, um sich die Splat-Methode anzusehen, da alles in Ruby verfügbar ist. Ich habe keine Ahnung, wo es ist, aber sobald Sie das haben, werden Sie sehen, dass es ein fordurch das Array läuft und den Hash erstellt.

Sie würden nach dem Code in der Kerndokumentation suchen . Wenn Sie es nicht finden können (ich konnte es nicht finden), würden Sie versuchen, einen Code wie diesen zu schreiben (der funktioniert, aber KEIN Ruby-ähnlicher Code ist):

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"]

und dann kann die Ruby-Bande Ihnen sagen, warum Ihr Code albern, schlecht oder einfach falsch ist.

Wenn Sie bis hierher gelesen haben, lesen Sie die Hash- Dokumentation zur Initialisierung durch.

Grundsätzlich werden sie durch einen mit mehreren Argumenten initialisierten Hash als Schlüsselwertpaare erstellt:

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

In Ihrem Beispiel würde dies also zu folgendem Hash führen:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.