[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