each で隣の要素を参照 #3

自分のことは棚に上げておいて人のコードにツッコミ。

おぉ、そうか ThreadLocal がなければ Thread.current をキーにすればいいだけなのか。うまい。常識?
それはさておき、

[1].each_with_prevsucc do |i|
   p [prev, i, succ]
end
# => [nil, nil, nil]

あり?あと、これネストするとまずい。
で、勝手に改造するとこうなる。

module Enumerable
   PREVS = Hash.new {|hash, key| hash[key] = []}
   SUCCS = Hash.new {|hash, key| hash[key] = []}
   $index = -1

   def each_with_prevsucc
      first = true
      index = $index += 1

      PREVS[Thread.current][index] = cur = nil
      each do |succ|
         if first
            first = false
            SUCCS[Thread.current][index] = succ
         else
            SUCCS[Thread.current][index] = succ
            $index = index
            yield cur
            PREVS[Thread.current][index] = cur
         end
         cur = succ
      end
      cur = SUCCS[Thread.current][index]
      SUCCS[Thread.current][index] = nil
      $index = index
      yield cur
      PREVS[Thread.current].pop
      SUCCS[Thread.current].pop
      $index -= 1
      self
   end
end

def prev; Enumerable::PREVS[Thread.current][$index] end
def succ; Enumerable::SUCCS[Thread.current][$index] end

[1].each_with_prevsucc do |i|
   p [prev, i, succ]
end

puts

(1..3).each_with_prevsucc do |i|
   p [prev, i, succ]
   (1..3).each_with_prevsucc do |j|
      print '   '
      p [prev, j, succ]
   end
   p [prev, i, succ]
   puts
end

こんな感じ?とりあえず動いているっぽい。

名前がかぶるとか、特異メソッドはそういう目的じゃねぇだろとか以前に Fixnum なんかだと特異メソッドが定義できない罠。instance_eval 使うときにそういうことは考えて玉砕済みだったりする。

irb(main):001:0> i = 10
=> 10
irb(main):002:0> def i.succ; 11 end
TypeError: can't define singleton method "succ" for Fixnum
        from (irb):2
        from :0
irb(main):003:0>