each で隣の要素を参照 #2

2007年06月13日 s99937 s99937 ruby わりかしeach_with_index派。かっこよくはないけど。ちなみに e_w_iはArrayではなくEnumerableにあります。

あ、いや、そりゃ誤解。Array ならランダムアクセス可能だから each_with_index でインデックスがあれば、前後の要素が簡単にわかるという話で、それは Enumerable の特性ではないという話です。

で、まぁ、なんか激しくよろしくない感じのコード。
instance_eval でブロックパラメータを指定できないので無理矢理ラッパーオブジェクトを作って method_missing で元のオブジェクトに委譲するという。
i.succ とかやると多分想定外の値が返ってくる。

class Iterator
   def initialize(array, index)
      @array = array
      @index = index
   end

   def method_missing(m, *args)
      @array[@index].__send__(m, *args)
   end

   def succ
      neighbor(1)
   end

   def prev
      neighbor(-1)
   end

   def neighbor(offset)
      @array[@index + offset]
   end

   def inspect
      @array[@index].inspect
   end

   def ==(x)
      return @array[@index] == x
   end
end


class Array
   alias :each_orig :each

   def each(&block)
      (0...length).each do |index|
         it = Iterator.new(self, index)
         it.instance_eval(&block)
      end
   end
end

(0..10).to_a.reverse.each do |i|
   p [neighbor(-2), prev, i, succ, neighbor(2)]
end