Я играю с Ruby, чтобы выучить язык. В настоящее время я пытаюсь обдумать концепцию волокон. Согласно этому ответу, они довольно часто используются для создания (бесконечных) внешних счетчиков. С другой стороны, кажется, что это пересекается с концепцией так называемых явных счетчиков.
Скажем, я хочу написать фрагмент кода, который запускает последовательные простые числа (да, следующий алгоритм имеет время выполнения O (страшно)). Я могу реализовать это с помощью волокон:
prime_fiber = Fiber.new do
primes = [2]
Fiber.yield 2
current = 1
loop do
current += 2
unless primes.find {|value| (current % value) == 0}
Fiber.yield current
primes << current
end
end
end
ARGV[0].to_i.times {print "#{prime_fiber.resume}, "}
Это не создает объект перечислителя сам по себе, хотя создать его из него несложно. Напротив, я также могу использовать явно определенный перечислитель, который имеет дополнительное преимущество, поскольку он уже является объектом перечислителя:
prime_enum = Enumerator.new do |yielder|
primes = [2]
yielder.yield 2
current = 1
loop do
current += 2
unless primes.find {|value| (current % value) == 0}
yielder.yield current
primes << current
end
end
end
ARGV[0].to_i.times {print "#{prime_enum.next}, "}
# I could also write:
# p prime_enum.first(ARGV[0].to_i)
Оба метода позволяют мне реализовать какие-то сопрограммы, и они кажутся мне взаимозаменяемыми. Итак, когда я предпочитаю одно другому? Существует ли общепринятая практика? Мне трудно уложить в голове все эти идиомы, поэтому заранее извиняюсь, если это сочтут глупым вопросом.