each_with_prevsucc

eachで回してるときの次の要素がほしい - Greenbear Diary (2007-06-12)
あるある。僕の解答。

module Enumerable
    PREVS = {}
    SUCCS = {}
    def each_with_prevsucc
        first = true
        PREVS[Thread.current] = cur = nil
        each do |succ|
            if first
                first = false
            else
                SUCCS[Thread.current] = succ
                yield cur
                PREVS[Thread.current] = cur
            end
            cur = succ
        end
        cur = SUCCS[Thread.current]
        SUCCS[Thread.current] = nil
        yield cur
        PREVS.delete Thread.current
        SUCCS.delete Thread.current
        self
    end
end
def prev; Enumerable::PREVS[Thread.current]; end
def succ; Enumerable::SUCCS[Thread.current]; end

[1,2,3,4,5].each_with_prevsucc do |item|
  p [prev, item, succ]
end
$ ruby prevsucc.rb
[nil, 1, 2]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, nil]

ところで each_with_* って名前が嫌い。長すぎ。代替案はないんだけど。

関係ないけど、enumerator の Enumerable#each_slice や each_cons を標準装備して欲しいです。