Ruby 2.6が出て2ヶ月が経過しているものの、まだ触ってなかったので新機能を調べていたら、関数合成ができるようになっていたのを知った。
これを使えば多少の加工だったらmapを2周したりしなくて済むんじゃないか?と思って実験してみた。
Procを先に定義するパターン
先に定義してあるので、mapしているところは見易いしわかりやすい。けれど、やっぱり先に定義したくない。
a = -> (x) { x.upcase } b = -> (x) { x.strip } ["abc ", " def", " ghi "].map(&(a >> b)) => ["ABC", "DEF", "GHI"]
Procを定義せずにto_procを使うパターン
先に定義せずにすると、こうなる。しかし、これはこれでto_proc
がやかましい…。
["abc ", " def", " ghi "].map(&(:upcase.to_proc >> :strip.to_proc)) => ["ABC", "DEF", "GHI"]
injectを使うパターン
配列に定義したsymbolをto_procしてinjectで合成する。カッコイイ。けれど、長い。
["abc ", " def", " ghi "].map(&([:upcase, :strip].map(&:to_proc).inject(&:>>))) => ["ABC", "DEF", "GHI"]
理想の書き方
動かないけれど、理想の書き方は…
["abc ", " def", " ghi "].map(&(:upcase >> :strip)) # => Not working...
みたいな感じがいいなぁと思う。
Array型をオープンクラスしてcompose
関数とかを追加するのがいいのかもしれない。
class Array def compose self.map(&:to_proc).inject(&:>>) end end
["abc ", " def", " ghi "].map(&([:upcase, :strip].compose)) => ["ABC", "DEF", "GHI"]
やらんけど。