lambda_driver
カッコよくコードが書ける。
Rubyで関数合成とかしたいので lambda_driver.gem というのを作った - ( ꒪⌓꒪) ゆるよろ日記LambdaDriver drives your code more functional.
yuroyoro/lambda_driver
だそうです。カッコいいなら使わない手はない。
使ってみた
最近書いてるコードから抜粋
普通に書いた場合
require 'open-uri'
require 'rexml/document'
class ThumbInfo
THUMB = "http://ext.nicovideo.jp/api/getthumbinfo/"
ID_REGEX = /^((sm|nm)(\d+)$/
def initialize(str)
@doc =
if str =~ ID_REGEX
build(open(THUMB + str))
elsif str.kind_of?(String)
build(str)
else
raise 'invalid source'
end
end
def build(str)
doc = REXML::Document.new(str)
validate(doc)
elems = doc.get_elements('nicovideo_thumb_response/thumb')
elems.first
end
def validate(doc)
#略
doc #問題なければそのまま返す
end
end
lambda_driverを使った場合
require 'open-uri'
require 'rexml/document'
require 'lambda_driver'
class ThumbInfo
THUMB = "http://ext.nicovideo.jp/api/getthumbinfo/"
ID_REGEX = /^((sm|nm)(\d+)$/
def initialize(str)
build = REXML::Document._.new >> method(:validation) >> (:get_element & 'nicovideo_thumb_response/thumb') >> :first
@doc =
if str =~ ID_REGEX
THUMB._.+ >> method(:open) >> build < str
elsif str.kind_of?(String)
build < str
else
raise 'invalid source'
end
end
def validate(doc)
#略
doc #問題がなければそのまま返す
end
end
ほーん、で?
とにかく build が全く違います。
いちいちメソッドを作っていたのですが、それがキレイサッパリなくなり、initializeに入ってしまいました。
buildを他のメソッドからも使うならばともかく、使わないならばスコープを制限できて有効です。
しかも、一時変数を使う必要がありません。
バイバイ、docとelemsよ( ´_ゝ`)/~~
さらに、lambda_driverを使ったbuildは左から右へと処理の順番が明示できているので、可読性もそこまで低くない(はず)
「ふむふむ、REXML::Document.newして、validateして、'nicoなんとか'でget_elementsして、firstするんだな」とスラスラ理解できるようになったらヤミツキになるでしょう。
もう一つの違いと言えば、build(open(THUMB + str))が THUMB._.+ >> method(:open) >> build < strになっているところでしょうか。
ネストネストしてるのは見た目にもなんだか嫌ですし、かと言って一時変数を作るのも面倒です。
これもlambda_driverを使えば、左から右へと処理を流して、最後にちょこっとstrを適用してあげれば終わりです。
「THUMBを+してopenしてbuildするものにstrを適用する」と考えましょう。
1人でQ&A
※それぞれの質問者は特定の個人ではなく私の妄想です。
Q. いきなりこんなこと言われても訳が分かりません (20代男性)
A.関数型言語をやったことがある人なら違和感なく使えるようになるかもしれませんが、それでもRubyのProcとSymbolとMethodに関する知識がないと厳しいかもしれません。
ライブラリに依存した書き方なので、仕事で使うことはまずないでしょうし、「好きな人だけが自分のスタイルで書けるときに楽しく書けば良い」と思います。
Q.「カッコいいので使えるようになりたいです。どうすればいいですか」(30代男性)
A.
に使い方が載っているので、そのコードを実際に動かしてみると何か掴めるかも。
実装も見ると色々勉強になります。
のメソッドは大事です。
[Ruby] ブロックとProcをちゃんと理解する - Qiita
【ruby】ブロックの変わりにProcオブジェクトを引数に渡す - tanihiro.log
RubyのブロックとProcは密接な関係があるので、arr.map(&:to_s)のような使い方が分かれば、他の部分でも応用が利くかも。
最後に
さっきも述べたように、「好きな人だけが使えばいい」と思うので、別に「これ使おうぜ!」みたいな感じではないです。
「多様性は善」です。
ここまで読んでいただきありがとうございます。
そしてGemの開発者のyuroyoroさんに最大限の感謝を。