Нет неявного преобразования Struct в Array - PullRequest
0 голосов
/ 23 марта 2020

У меня был случай, когда я работал с массивом структур и хотел transpose их, хотя и встретил ошибку:

TypeError (no implicit conversion of Struct into Array)

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

Итак, мой вопрос состоит из двух частей:

  • если я могу, как мне реализовать это неявное преобразование?
  • во-вторых, почему это так? Почему структуры не могут быть неявно преобразованы в массивы, но могут быть явно преобразованы?

Вот минимальный пример для выдачи ошибки:

S = Struct.new(:a, :b)

a = S.new(1, 2)
# => #<struct S a=1, b=2>
b = S.new(3, 4)
# => #<struct S a=3, b=4>

[a, b].transpose
# TypeError (no implicit conversion of S into Array)

[a, b].map(&:to_a)
# => [[1, 2], [3, 4]]

# Therefore, the extra step I'd have to take to transpose:
[a, b].map(&:to_a).transpose
# => [[1, 3], [2, 4]]

Заранее спасибо за любую помощь .

Ответы [ 2 ]

1 голос
/ 23 марта 2020

если я могу, как мне реализовать это неявное преобразование?

Вы можете передать блок в Struct.new и затем определить свой метод там:

S = Struct.new(:a, :b) do
  alias_method :to_ary, :to_a
end

во-вторых, почему это так? Почему структуры не могут быть неявно преобразованы в массивы, но могут быть явно преобразованы?

Это несколько философски, но to_ary, to_int, et c. указывают, что эти объекты действительно представляют массив, целое число и т. д. c. соответственно; они просто не совсем правильного типа.

Это отличается для однобуквенных вариантов to_a, to_i, которые указывают, что объект может попасть в массив, целое число и т. д. c , но их базовая структура сильно отличается или представляет только часть их истинной семантики.

1 голос
/ 23 марта 2020

Я на самом деле нашел ответ на этот вопрос во время исследования вопроса, поэтому я получу ответ, потому что я не мог найти ничего подобного при поиске ранее.

Ruby использует различные методы приведения для явного и неявного преобразования:

| Explicit | Implicit |
|----------|----------|
| to_i     | to_int   |
| to_s     | to_str   |
| to_a     | to_ary   | 
| to_h     | to_hash  |
|----------|----------|

Таким образом, проблема заключается в том, что структуры не имеют to_ary метода:

a.to_ary
# NoMethodError (undefined method `to_ary' for #<struct S a=1, b=2>)

Следовательно, если мы определим этот метод в рассматриваемой структуре, мы можем неявно преобразовать:

S.define_method(:to_ary) do
  self.to_a
end

[a, b].transpose
# => [[1, 3], [2, 4]]

Вуаля:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...