Слово yield на самом деле не имеет никакого особого значения в контексте Ruby. Это означает то же самое, что и в любом другом языке программирования, или в программировании и информатике в целом.
Обычно используется, когда какой-то контекст выполнения передает поток управления в другой контекст выполнения. Например, в Unix есть функция sched_yield
, которую поток может использовать для передачи ЦП другому потоку (или процессу). В сопрограммах термин yield
обычно используется для передачи управления от одной сопрограммы к другой. В C # есть ключевое слово yield
, которое используется методом итератора для передачи управления методу итерации .
И на самом деле это последнее использование в точности совпадает с использованием метода Enumerator::Yielder#yield
в Ruby, о котором вы спрашивали. Вызов этого метода приостановит перечислитель и передаст управление перечисляющему методу.
Пример:
fibs = Enumerator.new do |y|
a, b = 0, 1
y.yield a
loop do
y.yield b
a, b = b, a + b
end
end
puts fibs.next # 0
puts fibs.next # 1
puts fibs.next # 1
puts fibs.next # 2
puts fibs.next # 3
puts fibs.next # 5
puts fibs.next # 8
puts fibs.next # 13
puts fibs.next # 21
Как видите, существует бесконечный цикл. Очевидно, что если бы этот цикл работал сам по себе, он не принес бы особой пользы. Но поскольку каждый раз, когда он попадает в метод yield
, он отказывается от управления, пока не будет вызван снова, это будет генерировать числа Фибоначчи одно за другим, по существу представляя бесконечно длинный список всех чисел Фибоначчи.
Существует еще один метод, Fiber.yield
, который служит аналогичной цели. (На самом деле, я уже описал это выше, потому что Fiber
- это просто имя Ruby для сопрограмм.) Внутри Fiber
вы вызываете Fiber.yield
, чтобы вернуть управление контексту выполнения, который изначально предоставлял вам управление.
Наконец, есть ключевое слово yield
, которое используется внутри тела метода, чтобы передать управление блоку, который был передан в метод.
Обратите внимание, что, по крайней мере, в случае Enumerator
(т.е. в первом примере) вы можете дополнительно интерпретировать yield
как для получения , поскольку Enumerator
каждый раз выдает новое значение он звонит yield
.