Що робить оператор (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-ситуації (будь-коли, коли ви викликаєте це значення), splat розбиває масив вгору на окремі значення та при використанні в ситуації, подібній RHS (будь-коли, коли ви його використовуєте на деяких раніше не визначених змінних) вона групує окремі значення в масив. Так a,b,*c = d,e,f,*gвстановлюється a = d, b = e, c = [f, g0, g1, g2, ..., gn], де g = [g0, g1, g2, ..., gn]
чемпіон

2
Тільки для повноти, оператор бризки перетворює масив на головий список згідно з термінологією, що використовується у «Добре заземленому рубіністі» Девід А. Блек
Девід Берроуз

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

Як згадують усі, це "бризка". Шукати синтаксис Ruby неможливо, і я це задавав в інших питаннях. Відповідь на цю частину запитання - ви шукаєте далі

asterisk in ruby syntax

в Google. Google є для вас, просто покладіть на слова те, що бачите.

Anyhoo, як і багато коду Ruby, цей код досить щільний. The

line.split(/=|;/)

робить масив елементів SIX, 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"]

і тоді банда Ruby зможе сказати вам, чому ваш код нерозумний, поганий чи просто невірний.

Якщо ви читали це далеко, проведіть прочитане в документації Hash для ініціалізації.

В основному хеш, ініціалізований декількома аргументами, створює їх як пари ключових значень:

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

Отже, у вашому прикладі це призведе до наступного хешу:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.