続・tapの「使え方」

逆に露骨に副作用を起こすこともできる。

i = 0
i.tap { i += 1 }

2行目の式は 0 に評価され、副作用として i が 1 になる。ちょうどC言語の後置インクリメント演算子のようだ*1

tap のレシーバが評価されるのが(tap 内部で行われる)ブロックの呼び出しよりも先に行われるところが味噌だ。

この構造を使えば map のようにブロックの返り値が重要なループ的構造の最後で、ループ変数の更新を行うことができる。

j = 0
(1..10).map { |i| [i,j].tap { j+=i } }
=> [[1, 0],
 [2, 1],
 [3, 3],
 [4, 6],
 [5, 10],
 [6, 15],
 [7, 21],
 [8, 28],
 [9, 36],
 [10, 45]]

*1:Lisp の prog1 のようでもある。