Цель счетчиков - ленивая оценка.Когда вы вызываете each_slice, вы возвращаете объект перечислителя.Этот объект не рассчитывает весь сгруппированный массив заранее.Вместо этого он рассчитывает каждый «срез» по мере необходимости.Это помогает сэкономить память, а также дает вам немного гибкости в вашем коде.
В этом посте о переполнении стека содержится много информации, которую вы найдете полезной:
Какова цель класса Enumerator в Ruby
Чтобы дать вам краткий и сухой ответ на ваш вопрос «Почему я должен звонить to_a, когда ...», ответ - нет.Он еще не перебрал массив.До сих пор он просто определил объект, который говорит, что когда он проходит через массив, вам понадобятся элементы по два за раз.Затем вы можете либо заставить его выполнить вычисления для всех элементов перечислимого (вызывая to_a), либо вы можете альтернативно использовать next
или each
, чтобы пройти, а затем остановиться на полпути (возможно, рассчитать только половину).из них в отличие от вычисления их всех и отбрасывания второй половины).
Это похоже на то, как класс Range не создает список элементов в диапазоне.(1..100000) не создает массив из 100000 чисел, но вместо этого определяет объект с минимальным и максимальным значениями, и с ним можно выполнять определенные операции.Например (1..100000) .cover? (5) не создает массивный массив, чтобы увидеть, есть ли там это число, а просто видит, больше ли 5 или равно 1 и меньше или равно 100000.
Целью всего этого является производительность и гибкость.
Возможно, стоит подумать, действительно ли вашей реализации необходимо создать массив заранее или вы действительно можете снизить потребление ОЗУ.немного, перебирая перечислитель.(Если ваш реальный сценарий такой же простой, как вы описали, перечислитель мало чем поможет, но если массив на самом деле большой, перечислитель может вам сильно помочь).