Enumerable#injectはおかしくない
rubyのinjectにはバグがあるのか? - 計算機と戯れる日々
[1, 2, 2, 3, 2].inject([1]){|a,i|p a;p a[-1];a<<i} # => [1, 1, 2, 2, 3, 2] # >> [1] # >> 1 # >> [1, 1] # >> 1 # >> [1, 1, 2] # >> 2 # >> [1, 1, 2, 2] # >> 2 # >> [1, 1, 2, 2, 3] # >> 3
[1, 2, 2, 3, 2].inject([1]){|a,i|p a;p a[-1];a<<i if i!=a[-1]} # ~> -:1:in `block in <main>': undefined method `[]' for nil:NilClass (NoMethodError) # ~> from -:1:in `each' # ~> from -:1:in `inject' # ~> from -:1:in `<main>' # >> [1] # >> 1 # >> nil
「injectがおかしいせいで」と言っているが、結論から言うと、injectはおかしくない。injectはブロックの評価値を蓄えていくメソッドだ。
「a<<i if i!=a[-1]」という式はi==a[-1]なときにnilを返す。だから「nil[]」をやろうとしてエラーになっただけの話。ブロックの末尾に「a」と書いてあげよう。「i!=a[-1] ? a<<i : a」でもよい。
よって正解はコレ。
[1, 2, 2, 3, 2].inject([1]){|a,i|p a;p a[-1];a<<i if i!=a[-1]; a} # => [1, 2, 3, 2] # >> [1] # >> 1 # >> [1] # >> 1 # >> [1, 2] # >> 2 # >> [1, 2] # >> 2 # >> [1, 2, 3] # >> 3