ตัวดำเนินการ (unary) * ทำอะไรในรหัส Ruby นี้


174

รับรหัส Ruby

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

ฉันเข้าใจทุกอย่างในบรรทัดที่สองนอกเหนือจาก *โอเปอเรเตอร์แล้วมันกำลังทำอะไรอยู่และเอกสารนี้อยู่ที่ไหน? (อย่างที่คุณอาจคาดเดาการค้นหาเคสนี้พิสูจน์ได้ยาก ... )

คำตอบ:


271

*เป็นเครื่องหมายประกอบ

มันขยายArrayเข้าไปในรายการของการขัดแย้งในกรณีนี้รายการของการขัดแย้งกับHash.[]วิธีการ (หากต้องการความแม่นยำมากขึ้นจะขยายวัตถุใด ๆ ที่ตอบสนองต่อto_ary/ to_aหรือto_aใน Ruby 1.9)

เพื่อแสดงให้เห็นว่าสองข้อความต่อไปนี้เท่ากัน:

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

นอกจากนี้ยังสามารถใช้ในบริบทที่แตกต่างกันเพื่อดักจับอาร์กิวเมนต์ของเมธอดที่เหลือทั้งหมดในนิยามเมธอด ในกรณีนั้นมันไม่ขยาย แต่รวม:

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

บางส่วนรายละเอียดเพิ่มเติมได้ที่นี่


36
โดยทั่วไปเมื่อใช้ในสถานการณ์ที่คล้ายกับ LHS (เมื่อใดก็ตามที่คุณเรียกใช้ด้วยค่า) เครื่องหมายแยกจะแบ่งอาร์เรย์ออกเป็นค่าแยกกันและเมื่อใช้ในสถานการณ์ที่คล้ายกับ RHS (ทุกครั้งที่คุณใช้งาน ในตัวแปรที่ไม่ได้กำหนดก่อนหน้านี้บางตัว) มันจะจัดกลุ่มค่าที่แยกกันเป็นอาร์เรย์ ดังนั้นa,b,*c = d,e,f,*gตั้งค่า a = d, b = e, และ c = [f, g0, g1, g2, ... , gn], โดยที่ g = [g0, g1, g2, ... , gn]
rampion

2
เพียงเพื่อความสมบูรณ์ผู้ประกอบการสีแดงเปลี่ยนอาร์เรย์เป็นรายการเปล่าตามคำศัพท์ที่ใช้ใน 'รูบดิน Rubyist' โดย David A. Black
David Burrows

12
@rampion: ความคิดเห็นที่ยอดเยี่ยมคุณเพียงแค่ผสม LHS และ RHS มันเป็นอีกทางหนึ่ง
ThomasH

46

ตัวดำเนินการ splat คลายอาร์เรย์ที่ส่งผ่านไปยังฟังก์ชันเพื่อให้แต่ละองค์ประกอบถูกส่งไปยังฟังก์ชันเป็นพารามิเตอร์แต่ละตัว

ตัวอย่างง่ายๆ:

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

แค่นั้นแหละ!


6

ตามที่ทุกคนกล่าวถึงมันเป็น "เครื่องหมาย" กำลังมองหาไวยากรณ์ของทับทิมเป็นไปไม่ได้และฉันได้ถามคำถามนี้กับคำถามอื่น คำตอบสำหรับส่วนนั้นของคำถามคือคุณค้นหา

asterisk in ruby syntax

ใน Google Google อยู่ตรงนั้นเพื่อคุณเพียงแค่ใส่คำที่คุณเห็น

Anyhoo เช่นรหัส Ruby จำนวนมากรหัสนั้นค่อนข้างหนาแน่น

line.split(/=|;/)

first_name, mickey, last_name, mouse, country, usaทำให้อาร์เรย์ขององค์ประกอบหกแล้ว จากนั้นใช้เครื่องหมายเสียงเพื่อทำให้เป็นแฮช ตอนนี้คน Ruby จะส่งคุณไปดูวิธี Splat เสมอเนื่องจากทุกอย่างจะแสดงใน Ruby ฉันไม่รู้ว่ามันอยู่ที่ไหน แต่เมื่อคุณมีแล้วคุณจะเห็นว่ามันทำงานforผ่านอาร์เรย์และสร้างแฮช

คุณจะมองหารหัสในเอกสารหลัก หากคุณหาไม่เจอ (ฉันหาไม่ได้) คุณจะลองเขียนโค้ดแบบนี้ (ใช้งานได้ แต่ไม่ใช่โค้ดที่คล้าย 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"]

จากนั้นแก๊งทับทิมจะสามารถบอกคุณได้ว่าทำไมโค้ดของคุณถึงโง่เง่าไม่ดีหรือผิดธรรมดา

หากคุณอ่านมาไกลให้อ่านเอกสารHashเพื่อเริ่มต้น

โดยพื้นฐานแล้วแฮชที่เริ่มต้นด้วยอาร์กิวเมนต์หลายตัวสร้างเป็นคู่ของค่าคีย์:

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

ดังนั้นในตัวอย่างของคุณสิ่งนี้จะนำไปสู่การแฮชต่อไปนี้:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.