Я постараюсь объяснить, что он делает по крупицам, так что вы можете попытаться обернуть его вокруг.
Enumerator.new do |yielder|
end
Итак, вы создаете экземпляр перечислителя, который будет работать над переменной с именем yielder
.
Внутри его области вы устанавливаете некоторые локальные переменные (которые будут сохраняться при повторном использовании объекта):
number = 0
count = 1
А затем вы устанавливаете цикл, который увеличивает number
на count
и count
с помощью 1
, а затем вызовите yield для вашего аргумента, передав ему number
в качестве аргумента.
loop do
number += count
count += 1
yielder.yield number
end
5.times
повторяет блок, переданный ему 5 раз.Блок
-> { print triangular_numbers.next, " " }
вызывает print
, который принимает n
аргументов и объединяет части для формирования строки, но не добавляет символ новой строки.
Первый аргумент - наш перечислитель nextвзаимодействие (triangular_numbers.next
), которое будет вычислять текущий номер и доходность вызова для Enumerator::Yielder
, который неявно создан, обрабатывая элемент управления обратно к вызывающему Fiber
вместе со всеми переданными ему аргументами.
(Все счетчики реализованы как «Волокна» в МРТ)
Так что вызов yielder.yield
аналогичен вызову Fiber.yield
и позволит циклу 5.times
работать и возвращать number
1.