Fiber で FizzBuzz

ruby-list で

  • Fiber のサンプルがイケてない。
  • Fiber.yield, Fiber#resume の戻り値使えよ。

と言われてたので、そんな FizzBuzz に挑戦してみた。

class FizzBuzz
  def initialize
    @buzz = Fiber.new do |i|
      loop do
        print "buzz"
        i = Fiber.yield(i+1)
      end
    end

    @fizz = Fiber.new do |i|
      loop do
        print "fizz"
        if i%5 == 0
          i = Fiber.yield(@buzz.resume(i))
        else
          i = Fiber.yield(i+1)
        end
      end
    end
  end

  def run(i, n)
    while i <= n
      case
      when i%3 == 0
        i = @fizz.resume(i)
      when i%5 == 0
        i = @buzz.resume(i)
      else
        print i
        i = i + 1
      end

      puts
    end
  end
end

FizzBuzz.new.run(1, 40)

# >> 1
# >> 2
# >> fizz
# >> 4
# >> buzz
# >> fizz
# >> 7
# >> 8
# >> fizz
# >> buzz
# >> 11
# >> fizz
# >> 13
# >> 14
# >> fizzbuzz
# >> 16
# >> 17
# >> fizz
# >> 19
# >> buzz
# >> fizz
# >> 22
# >> 23
# >> fizz
# >> buzz
# >> 26
# >> fizz
# >> 28
# >> 29
# >> fizzbuzz
# >> 31
# >> 32
# >> fizz
# >> 34
# >> buzz
# >> fizz
# >> 37
# >> 38
# >> fizz
# >> buzz

40 まで数えてしまうのは世界のナベアツの影響かな。