(Unary) * operatörü bu Ruby kodunda ne yapar?


174

Ruby kodu verildiğinde

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

*Operatör dışında ikinci satırdaki her şeyi anlıyorum - ne yapıyor ve bunun için belgeler nerede? (tahmin edebileceğiniz gibi, bu vakayı aramak zor oluyor ...)

Yanıtlar:


271

*Olduğu uyarısı operatörü.

Bir Arrayargüman listesine, bu durumda Hash.[]yönteme ait bir argüman listesine genişler . (Daha kesin olmak gerekirse, to_ary/ to_aveya to_aRuby 1.9'da yanıt veren herhangi bir nesneyi genişletir .)

Açıklamak gerekirse, aşağıdaki iki ifade eşittir:

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

Yöntem tanımında kalan tüm yöntem bağımsız değişkenlerini yakalamak için farklı bir bağlamda da kullanılabilir. Bu durumda, genişlemez, ancak birleştirir:

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

Burada biraz daha ayrıntılı bilgi .


36
Genel olarak, LHS benzeri durumda kullanıldığında (bir değer üzerinde istediğiniz zaman çağırdığınızda), splat bir diziyi ayrı değerlere böler ve RHS benzeri bir durumda kullanıldığında (bunu her kullandığınızda) önceden tanımlanmamış bazı değişkenlerde), ayrı değerleri bir dizi halinde gruplandırır. Yani a,b,*c = d,e,f,*ga = d, b = e ve c = [f, g0, g1, g2, ..., gn] ayarlar, burada g = [g0, g1, g2, ..., gn]
rampion

2
Tamlık için, uyarıcı operatörü David A. Black tarafından 'The Well Grounded Rubyist' de kullanılan terminolojiye göre bir diziyi çıplak bir listeye dönüştürüyor
David Burrows

12
@ rampion: Harika yorum, sadece LHS ve RHS'yi karıştırdınız. Tam tersi.
ThomasH

46

Uyarıcı işleci, işleve geçirilen bir diziyi paketinden çıkarır, böylece her öğe işleve ayrı bir parametre olarak gönderilir.

Basit bir örnek:

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

Bu kadar!


6

Herkesin söylediği gibi, bu bir "uyarısı" dır. Ruby sözdizimini aramak imkansız ve bunu diğer sorularda sordum. Sorunun bu kısmının cevabı,

asterisk in ruby syntax

Google'da. Google sizin için orada, gördüklerinizi kelimelere dökün.

Anyhoo, bir çok Ruby kodu gibi, bu kod oldukça yoğundur.

line.split(/=|;/)

bir dizi SIX öğesi yapar first_name, mickey, last_name, mouse, country, usa,. Daha sonra uyarısı bunu bir Hash haline getirmek için kullanılır. Şimdi Ruby insanlar her zaman Ruby'de her şey ortaya çıktığı için sizi Splat yöntemine bakmaya gönderirler. Nerede olduğu hakkında hiçbir fikrim yok, ama bir kez sahip olduğunuzda,for dizi üzerinden ve karma oluşturur.

Çekirdekteki kodu ararsınız belgelerde ararsınız. Eğer bulamıyorsanız (bulamadım), böyle bir kod yazmaya çalışırsınız (çalışır, ancak Ruby benzeri kod DEĞİLDİR):

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

ve sonra Ruby çetesi size kodunuzun neden aptal, kötü ya da sadece yanlış olduğunu söyleyebilecektir.

Şimdiye kadar okuduysanız, Hash'i , başlatma belgelerini .

Temel olarak birkaç argümanla başlatılan bir karma, bunları anahtar değer çiftleri olarak oluşturur:

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

Yani örneğinizde bu, aşağıdaki Karma'ya yol açacaktır:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.