Почему знак здесь используется внутри определения массива?

def initialize(apps, catch=404)
  @apps = []; @has_app = {}
  apps.each { |app| add app }

  @catch = {}
  [*catch].each { |status| @catch[status] = true }
end

В этом методе из Rack::Cascade, что для чего служит splat(*) в коде [*catch]?

Я думал, что в аргументах метода используется знак, чтобы указать, когда у вас будет неопределенное количество параметров.

Здесь знак имеет другое значение?


person uzo    schedule 13.09.2009    source источник


Ответы (3)


Он создает единый плоский массив для улова

Я не уверен, что кто-то полностью понимает оператор splat. Много раз он удаляет один уровень "массива", но не удаляет последний уровень.

По крайней мере, в этом случае получить его можно. Он создает один уровень массива для параметра catch независимо от того, является ли catch одним числом или массивом чисел.

>> t = [*404]
=> [404]
>> t = [*[404,405,406]]
=> [404, 405, 406]
person DigitalRoss    schedule 13.09.2009
comment
Хорошая ссылка: github.com/mischa/splat. Спасибо. Довольно запутанная вещь. Но удаление одного уровня массивности кажется самым простым способом подумать об этом. Хорошо сказано. - person uzo; 13.09.2009

Я думаю, что лучший способ понять это — посмотреть, что происходит в irb.

Итак, давайте инициализируем пустой хеш, @catch:

>> @catch = {}
=> {}
>> @catch.class
=> Hash

Теперь давайте посмотрим, что происходит, когда параметр catch принимает значение по умолчанию 404:

>> catch=404
=> 404
>> [*catch].each { |status| @catch[status] = true }
=> [404]
>> @catch[404]
=> true

Это дает нам лучшее представление о том, что происходит. Мы видим, что оператор splat используется для построения Hash ответов. Номера ответов используются как key, а true устанавливается как value. Таким образом, независимо от того, сколько предметов у нас есть в улове, мы все равно можем построить Hash.

>> catch=[404, 301, 302, 303, 403]
=> [404, 301, 302, 303, 403]
>> [*catch].each { |status| @catch[status] = true }
=> [404, 301, 302, 303, 403]
>> @catch
=> {302=>true, 303=>true, 403=>true, 404=>true, 301=>true}

Надеюсь, это поможет. Вот ссылка, которая немного помогла мне:

http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/

person jluebbert    schedule 13.09.2009
comment
Ах! Это классно! Это напоминает мне ruby_koans: github.com/edgecase/ruby_koans - person jluebbert; 14.09.2009

Другой способ взглянуть на это: знак l-значения является жадным и содержит как можно больше соответствующих r-значений.

person JRL    schedule 13.09.2009