each_with_prevsucc の続き

each で隣の要素を参照 #3 - odz buffer

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

あり?あと、これネストするとまずい。

う、たしかに。あと、空リストでも yield しちゃう。id:odz さんの対策だと $index がマルチスレッドで変なことになるような気がする。自分流の修正版。

module Enumerable
    PREVSUCCS = {}
    def each_with_prevsucc
        prevsucc = [nil] * 3
        (PREVSUCCS[Thread.current] ||= []).unshift prevsucc
        first = true
        each do |e|
            (prevsucc << e).shift
            if first
                first = false
            else
                yield prevsucc[1]
            end
        end
        unless first
            (prevsucc << nil).shift
            yield prevsucc[1]
        end
        PREVSUCCS[Thread.current].shift
        self
    end
end
def prev; Enumerable::PREVSUCCS[Thread.current].first.first; end
def succ; Enumerable::PREVSUCCS[Thread.current].first.last; end

追記: id:odz さんの指摘の通りにバグ修正。