Ruby

RubyのFiberとEnumeratorでプロ生ちゃんgenerator

More than 1 year has passed since last update.

Ruby1.9から軽量スレッドFiberが追加されました。
generatorを作ってみましょう。

Fiber

Fiberはこんな感じです。

angel = Fiber.new do |msg|
  puts "プロ生ちゃんマジ天使!"
  Fiber.yield
  puts "プロ生ちゃんマジ天使!"
end

angel.resume #=> "プロ生ちゃんマジ天使!"
angel.resume #=> "プロ生ちゃんマジ天使!"

これだと puts "プロ生ちゃんマジ天使!" を何度も書かないといけないので面倒くさいです。

angel = Fiber.new do |msg|
  loop do
    puts Fiber.yield
  end
end

10.times { angel.resume "プロ生ちゃんマジ天使!" } #=> 
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"
"プロ生ちゃんマジ天使!"

Enumerator

Enumeratorでも同じことをやってみましょう。
外部イテレータとしての機能はFiberで実装されています。

angel = Enumerator.new do |msg|
  loop do
    msg << "プロ生ちゃんマジ天使!"
  end
end

angel.take(10).join(' ') #=>
"プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使! プロ生ちゃんマジ天使!"

まとめ

FiberとEnumeratorを使ってgeneratorを作ってみました。
無限リストなどを処理するときは、Enumerator::Lazyをどうぞ。