LoginSignup
10
10

More than 5 years have passed since last update.

lambda_driverがカッコいい

Last updated at Posted at 2014-09-19

lambda_driver

カッコよくコードが書ける。
Rubyで関数合成とかしたいので lambda_driver.gem というのを作った - ( ꒪⌓꒪) ゆるよろ日記

LambdaDriver drives your code more functional.
yuroyoro/lambda_driver

だそうです。カッコいいなら使わない手はない。

使ってみた

最近書いてるコードから抜粋

普通に書いた場合

before.rb
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を使った場合

after.rb
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.

yuroyoro/lambda_driver

に使い方が載っているので、そのコードを実際に動かしてみると何か掴めるかも。
実装も見ると色々勉強になります。

 

class Object
class Symbol
class Proc
class Method

のメソッドは大事です。

 

[Ruby] ブロックとProcをちゃんと理解する - Qiita
【ruby】ブロックの変わりにProcオブジェクトを引数に渡す - tanihiro.log

RubyのブロックとProcは密接な関係があるので、arr.map(&:to_s)のような使い方が分かれば、他の部分でも応用が利くかも。

最後に

さっきも述べたように、「好きな人だけが使えばいい」と思うので、別に「これ使おうぜ!」みたいな感じではないです。
「多様性は善」です。

ここまで読んでいただきありがとうございます。

そしてGemの開発者のyuroyoroさんに最大限の感謝を。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10