Ruby の #tap の面白い挙動

Ruby#tap はレシーバをブロック引数に渡して、レシーバ自身を返すメソッドです。

x = 42
p x.tap{ |n| p n + n }
# output:
# 84
# 42

ブロック内でレシーバ自身を書き換えても書き換える前の値が返ってくる

この #tap の面白い挙動なんですが、ブロック内でレシーバ自身を書き換えても書き換える前の値が返ってきます。

x = 42
p x.tap{
    x = 3.14
}
# => 42
p x
# => 3.14

これはしらなかったなー。