Нет неявного преобразования Enumerator в Array - PullRequest
0 голосов
/ 01 ноября 2018

у меня есть:

qs = ["all=true", "limit=-1"]
value = ["agent", "service", "token"]

Этот код:

qs.concat value.map do |val|
  "#{field}=#{val}"
end

заканчивается следующей ошибкой:

`concat': no implicit conversion of Enumerator into Array (TypeError)`

тогда как этот код:

values = value.map do |val|
  "field=#{val}"
end
qs.concat values

нет.

В чем разница между ними?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Когда вы говорите qs.concat value.map do |val|, к чему относится do? (Подсказка: не value.map!)

Используйте скобки, если не уверены.

qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat(value.map do |val|
  "field=#{val}"
end)

{...} будет более типичным, чем do...end, и приоритет сработает, поэтому вам не нужны круглые скобки, так как {...} действительно идет к value.map, а не к qs.concat. Это также работает:

qs=["all=true", "limit=-1"]
value=["agent", "service", "token"]
qs.concat value.map { |val|
  "field=#{val}"
}
0 голосов
/ 01 ноября 2018

Ваша проблема вызвана различными приоритетами при предоставлении блоков для вызовов методов. В вашем случае вы используете следующий код:

qs.concat value.map do |val|
  "#{field}=#{val}"
end

Ruby предполагает, что вы имеете в виду следующее:

qs.concat(value.map) do |val|
  "#{field}=#{val}"
end

То есть Ruby передает блок первому методу (т.е. qs.concat), который игнорирует блок. Поскольку Array#map возвращает Enumerator, если вы не пропустили блок, вы получите ошибку, которую видели.

Чтобы решить эту проблему, вы можете использовать форму фигурных скобок для прохождения блока, т. Е .:

qs.concat value.map { |val|
  "#{field}=#{val}"
}

В этой форме блок всегда передается «последнему» методу, т.е. ваш map.

В любом случае, если есть какие-либо сомнения относительно приоритета оператора, всегда полезно использовать явные скобки или промежуточные переменные, чтобы прояснить как читателям, так и интерпретатору Ruby, как должен работать ваш код .

...