Какова цель передачи блока в enum_for в Ruby? - PullRequest
0 голосов
/ 08 апреля 2020

Согласно официальным документам Ruby, есть два способа вызова enum_for:

enum_for(method = :each, *args) → enum
enum_for(method = :each, *args){|*args| block} → enum

Мне кажется, я достаточно хорошо понимаю счетчики Ruby в общем. И поэтому я понимаю, что делает вызов enum_for без блока. Но я не совсем понимаю, какова цель вызова его с помощью блока.

Описание в документации: «Если блок указан, он будет использован для расчета размера перечислителя без необходимости повторять это ", не очень полезно.

1 Ответ

1 голос
/ 08 апреля 2020

В примере из документации они установили метод repeat, который будет принимать перечислимое значение и давать его значения n раз. Итак, для массива:

array = [1, 2, 3, 4, 5]

вызов repeat(3) даст:

1
1
1
2
2
2
...

Итак, у меня есть array и вызов enum = array.repeat(3), и теперь я хочу знать, как много элементов в enum. Я мог бы go пройти и настроить счетчик:

counter = 0; array.repeat(3) { |element| counter += 1 }

и знать, что в enum есть 15 элементов, или я не являюсь компьютером и обладаю предварительными знаниями о том, что делает repeat Я мог бы просто сказать array.size * 3 и получить 15.

Но это все излишне, потому что Enumerator имеет метод size, поэтому было бы неплохо, если бы я мог просто скажем enum.size. Тем не менее, размер просто возвращает nil, потому что он не может вычислить размер лениво, поэтому я должен был бы использовать count, который просто будет перебирать и подсчитывать элементы, как наше наивное решение. Я могу сказать size, как лениво вычислять размер, передавая блок в enum_for (вырезано из документов)

to_enum(__method__, n) do # __method__ is :repeat here
  sz = size     # Call size and multiply by n...
  sz * n if sz  # but return nil if size itself is nil
end

и теперь он ведет себя как наш второй метод. Для варианта использования, подобного этому, это может показаться лишь незначительным выигрышем, но если я повторю массив из 1000 элементов 1 миллион раз? Или что, если мой enum работает с внешним сервисом или выполняет много дорогих вычислений? эта небольшая оптимизация могла бы сэкономить немало циклов и избежать ненужной работы, когда все, что вам нужно было всего.

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