Что делает оператор (унарный) * в этом коде Ruby?

Учитывая код Ruby

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

Я понимаю все во второй строке, кроме оператора * - что он делает, и где это документация для этого? (как вы могли догадаться, поиск этого случая трудно...)

Ответ 1

* Является оператором splat.

Он расширяет 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

Здесь представлена более подробная информация.

Ответ 2

Оператор 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

Что это!

Ответ 3

Как все говорят, это "знак". Поиск синтаксиса Ruby невозможно, и я задал это в других вопросах. Ответ на эту часть вопроса заключается в том, что вы

asterisk in ruby syntax

в Google. Google есть для вас, просто поместите то, что вы видите в словах.

Anyhoo, как и много кода Ruby, этот код довольно плотный.

line.split(/=|;/)

создает массив из элементов SIX, first_name, mickey, last_name, mouse, country, usa. Затем splat используется, чтобы превратить это в хэш. Теперь люди 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"}