リングバッファを作ってみました

固定長の配列をぐるぐる使い回すデータ構造を実装してみました。真面目にindexで次の格納場所を管理しています。配列をpush、shiftするだけの素朴な実装と性能がどれくらい違うのでしょう。そのうち確認しようと思います。
あと、Arrayだと[]メソッドにRangeオブジェクトを入れられるのですが、面倒だったのでここでは対応していません。

class RingBuffer
  include Enumerable

  def initialize(size = 0)
    @size = size
    @buf = []
    @index = 0
  end

  def <<(x)
    if @buf.size < @size
      @buf << x
    else
      @buf[@index] = x
      @index += 1
      @index = 0 if @index >= @size
    end
  end

  def each(&block)
    @buf[@index .. @buf.size].each(&block)
    @buf[0 ... @index].each(&block)
  end

  def clear
    @buf.clear
    @index = 0
  end

  def [](start, length = nil)
    args = if @buf.size < @size
             [start]
           else
             index = @index + start
             [(index < @size) ? index : index - @size]
           end
    args << length if length
    @buf[*args]
  end
end

if $0 == __FILE__
  buf = RingBuffer.new(3)
  p buf.to_a         # => []
  
  buf << :a << :b
  p buf.to_a         # => [:a, :b]
  
  buf << :c
  p buf.to_a         # => [:a, :b, :c]
  
  buf << :d
  p buf.to_a         # => [:b, :c, :d]
  
  buf << :e
  p buf.to_a         # => [:c, :d, :e]
  
  p buf[1]           # => :d
  p buf[1, 2]        # => [:d, :e]

  buf.clear
  p buf.to_a         # => []
end