私は言語を学ぶために Ruby をいじっています。現在、私は繊維の概念に頭を悩ませようとしています。この回答によると、それらは(無限の)外部列挙子を作成するためにかなり頻繁に使用されます。一方、これはいわゆる明示的な列挙子の概念と重複しているようです。
たとえば、連続する素数を発生させるコード スニペットを書きたいとします (そうです、次のアルゴリズムの実行時間は O(scary) です)。ファイバーを使用して実装できます。
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)
どちらの方法でも、ある種のコルーチンを実装することができ、私には交換可能のようです。では、いつどちらを優先するのでしょうか。一般的に合意された慣行はありますか?これらのイディオムをすべて頭に入れるのは難しいと思うので、これがばかげた質問と見なされる場合は、事前にお詫び申し上げます。