Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

inject内部で条件付きな式を使う場合注意すること

inject内部で条件付きな式を使う場合、
かならず初期値*1を返すようにしないと
エラーを吐きます。
実例を挙げると、

ary.inject("") {|ary, item| ary << item if item > 'e'; ary}

といったように初期値を吐き出すようにしないといけません。

実際のところ

 p ary
#["a", "n", "t", "c", "v"]

てな配列がある状態で、"e"より後の文字を加算する……なんてケースを考えてみます。
何も考えず、以下のように書くと

ary.inject("") {|ary, item| ary << item if item > 'e'}

Nilクラスになっているという旨のエラーが。

NoMethodError: undefined method `<<' for nil:NilClass

試しに、

ary.inject("") {|ary, item| p ary << item if item > 'e'; p ary}

と書き換えてみて出力をみてみると

""
"n"
"n"
"nt"
"nt"
"nt"
"ntv"
"ntv"

てな塩梅で、一致していない場合はそもそもary自体が存在していないことがわかります。
ただし、後ろにくっつけたaryのお陰で現状の配列を吐き出して次に行くためエラーにならない……てな寸法のようです。
難しいですね

*1:アキュムレーターだの累算器だのといわれるもの