Apa yang dilakukan oleh (unary) * operator dalam kode Ruby ini?

174

Diberi kode Ruby

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

Saya mengerti segala sesuatu di baris kedua selain dari *operator - apa yang dilakukannya dan di mana dokumentasi untuk ini? (seperti yang Anda duga, mencari kasing ini terbukti sulit ...)

David Burrows
sumber

Jawaban:

271

The *adalah percikan operator.

Ini memperluas Arraydaftar argumen, dalam hal ini daftar argumen untuk Hash.[]metode ini. (Lebih tepatnya, itu memperluas objek yang merespons to_ary/ to_a, atau to_adi Ruby 1.9.)

Sebagai ilustrasi, dua pernyataan berikut ini sama:

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

Ini juga dapat digunakan dalam konteks yang berbeda, untuk menangkap semua argumen metode yang tersisa dalam definisi metode. Dalam hal itu, itu tidak berkembang, tetapi menggabungkan:

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

Beberapa informasi lebih rinci di sini .

Molf
sumber
36
Secara umum, ketika digunakan seperti dalam situasi seperti LHS (setiap kali Anda memohonnya pada suatu nilai), percikan membagi array menjadi nilai-nilai terpisah, dan ketika digunakan dalam situasi seperti RHS (setiap kali Anda menggunakannya pada beberapa variabel yang sebelumnya tidak ditentukan), ia mengelompokkan nilai-nilai yang terpisah menjadi sebuah array. Jadi a,b,*c = d,e,f,*gset a = d, b = e, dan c = [f, g0, g1, g2, ..., gn], di mana g = [g0, g1, g2, ..., gn]
rampion
2
Hanya untuk kelengkapan, operator gambar percikan berubah array ke dalam daftar telanjang sesuai dengan terminologi yang digunakan dalam 'The Rubyist Nah Beralas' oleh David A. Hitam
David Burrows
12
@rampion: Komentar luar biasa, Anda hanya mencampur LHS dan RHS. Itu sebaliknya.
ThomasH
46

Operator percikan membuka paket array yang dilewatkan ke fungsi sehingga setiap elemen dikirim ke fungsi sebagai parameter individu.

Contoh sederhana:

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

Itu dia!

BJ Homer
sumber
6

Seperti yang semua orang sebutkan, itu adalah "percikan". Mencari sintaksis Ruby tidak mungkin, dan saya sudah menanyakan hal ini dalam pertanyaan lain. Jawaban untuk bagian pertanyaan itu adalah Anda mencari

asterisk in ruby syntax

di Google. Google ada untuk Anda, cukup cantumkan apa yang Anda lihat dalam kata-kata.

Anyhoo, seperti banyak kode Ruby, kode itu cukup padat. Itu

line.split(/=|;/)

membuat array elemen ENAM first_name, mickey, last_name, mouse, country, usa,. Kemudian percikan digunakan untuk membuatnya menjadi Hash. Sekarang orang Ruby selalu mengirim Anda untuk melihat metode Splat, karena semuanya terbuka di Ruby. Saya tidak tahu di mana itu, tetapi begitu Anda memilikinya, Anda akan melihat bahwa ia menjalankan forarray dan membangun hash.

Anda akan mencari kode dalam dokumentasi inti . Jika Anda tidak dapat menemukannya (saya tidak bisa), Anda akan mencoba untuk menulis beberapa kode seperti ini (yang berfungsi, tetapi BUKAN kode seperti 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"]

dan kemudian geng Ruby akan dapat memberi tahu Anda mengapa kode Anda konyol, buruk, atau hanya salah.

Jika Anda sudah membaca sejauh ini, baca dokumentasi Hash untuk inisialisasi.

Pada dasarnya hash yang diinisialisasi dengan beberapa argumen membuatnya sebagai pasangan nilai kunci:

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

Jadi, dalam contoh Anda ini akan mengarah ke Hash berikut:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
Dan Rosenstark
sumber