ブロックなしRubyをやろうとすると関数型プログラ…うーんリストプロセッ、えーと感じ感じ
めっちゃいい話です。
ブロックを使わずに "レシーバを未定にし、メソッドの実引数のみ部分適用した Proc オブジェクトを生成" したいことが結構あります。
できないのでつらみがある。
でも Symbol に任意の引数をあらかじめ適用しておいてからレシーバを後挿し可能な Proc というものを得ることができればよさそうな気がしますね。
そんなかんじで Symbol を拡張した話をします。
そういう記事自体はすでに以前 blog に書いていた のですがタイムリーっぽい気がするので Qiita にも載せます。
class Symbol
def call(*argv)
case
when block_given?
-> obj { self.to_proc[obj, *argv, &proc] }
when argv.size > 0
-> obj { self.to_proc[obj, *argv] }
else
self.to_proc
end
end
end
p [[1,2,3],[2,4,6],[5,7,9]].map(&:inject.(:+))
p [[1,2,3],[2,4,6],[5,7,9]].map(&:select.(&:odd?))
p [[1,2,3],[2,4,6],[5,7,9]].map(&:slice.(1,1))
以前 gist に載せたコードから当該部分をまんま引っ張ってきただけです……。
引数の順番を入れ替える lambda でラップして、レシーバだけを未定なままにして Proc を得られるようにしてあります。
xs = (1..10)
xs.map(&:to_s.(2))
よさそうですね。
といっても見てのとおりちゃっちい作りなので使ってみるとこれだけだと不充分なこともあります。レシーバを後挿しにできるというかそれ以外のことはできないです。
前にこのコードを書きながらもう lambda driver あるよと思ったんだけど前に書いたときは自分で手を動かすことで関数型っぽいものに対する理解が深まるんじゃないかな-かなーという感じでした。
いまこうして Qiita に載せたのは単にタイムリーっぽい気がしたからという不純な動機からだったりしますが、まあでもこれくらいの短いコードから関数型っぽいものに対する理解が深まっていけばいいなーと思ってます。
追記1
続き があります。
追記2
わざわざカリー化して部分適用しなくてもよかったので直しました。