【速報】Ruby の trunk に pipeline operator がはいった

追記

pipeline operator の議論は RubyKaigi 2019 の Ruby Committers vs the World で話が出ていたみたいですね。

www.youtube.com

取り急ぎまとめ。
今日、Ruby の開発者会議に参加させて頂いて、さっき返ってきて ML みてたんですがいつの間にか pipeline operator がマージされていました。
思わず3度ぐらい ML と commit を見直してしまいました。
え、ほんまに???

開発者会議では議論されてなかったんですが、終わったあとに何があったんや…(会場の都合でオフライン勢は先に解散してオンライン勢で議論が続いていたみたい。
と、言うことでこの機能の提案自体は前から興味があったので現時点でどうなっているか簡単にまとめてみました。

|> でメソッド呼び出し

今までは以下のように . でメソッドを呼び出したんですが、

foo()
 .bar(1, 2)
 .display

|> でもメソッドを呼び出せるようになりました。

foo()
 |> bar 1, 2
 |> display

上記の違いをみてもらうとわかると思うんですが、今までは plus(5, 2).to_s(2) のようにメソッドチェーンする場合、 () を付ける必要がありました。
しかし |> を使用すると () をつけずに plus 5, 2 |> to_s(2) のようにメソッドチェーンする事が出来ます。
これにより plus 5, 2 というメソッド呼び出しをチェーンする場合、いちいち plus(5, 2) と書かずに plus 5, 2 |> to_s(2) というようにメソッドチェーンする事が出来ます。

使用例

def plus(a, b)
  a + b
end

# p plus(5, 2).to_s(2) と等価
p (plus 5, 2 |> to_s(2))
# => "111"


# x = (1..).take(10).map { |e| e * 2 }
x = (1.. |> take 10 |> map { |e| e * 2 })
# => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

こんな感じで |> を使うことが出来ます。
その他、詳しい使用例は Ruby 開発者会議の議事録を参照してください。

注意点

|> は優先順位が低いため代入演算子やメソッドの引数に渡す場合に注意があるようです。

p plus 5, 2 |> to_s(2)

の場合は

p(plus 5, 2) |> to_s(2)

と解釈され、

x = 1 + 2 |> to_s(2)

(x = 1 + 2) |> to_s(2)

のように解釈されるみたいです。
これを回避する場合は明示的に () をつけて処理する必要があります。

def plus(a, b)
  a + b
end
p (plus 5, 2 |> to_s(2))
# => "111"

x = (1 + 2 |> to_s(2))
p x
# => "11"

所感

これ、提案を見たときからめっちゃ便利そうーけど Ruby 的にはどうなんだろうなあ…と思っていたんですがあっさりマージされて面食らっています。
もうちょっと |> の記号とか議論されるのかと思っていましたが…。
で、実際書いてみてどうなのかと言われると慣れると『ああ、引数を渡したから () でくくって…』みたいなストレスがなくなるので意外としっくり来ますね。
Ruby はメソッド呼び出しで () を省略出来るのでかなり親和性が高いと思います。
なんというか書いてて気持ちがいいというか。
このあたりは実際に使ってみない事にはわからないと思うので『なんではいったの?』って思う人は1度使ってみてほしいです。
コードリーディングの面でいえば慣れるまでに時間がかかるとは思うんですが果たしてどうなるのか…。
ってか、Ruby 2.7 での追加機能がやばすぎてやばい。