みなさんRubyのlamda
を使っていますか?lamda
を使うとロジックを変数にいれて抽出するようなことが出来ます。これを使うと複雑なロジックを変数に入れて名前をつけられたり、いろいろとスッキリかけるケースが多そうな気がしてきたのメモしておきます📝
👇lamda
の基本的な使い方下記を参照してください
例えば、下記のようなブログの一覧の取得取得したあとにお気に入りが多いものだけを取得するロジックがあったとします。(DBで取得するときに除外すればいいじゃんという話は置いといて)
Blogs.where(published: true).to_a.select { |blog| blog.favorites.length > 100 }
これでも良いと思うんですが、除外するロジックが増えてきた場合にどうでしょう👀
Blogs.where(published: true).to_a.select do |blog| blog.favorites.length > 100 && blog.comments.length > 0 end
select
の中身がごちゃごちゃしてきたのと、do..end
が入って行数が増えきて、ちょっと辛くなってきましたね😅
こういうときにはlamda(proc)
を使ってあげるとスッキリかけます💪
下記がlamda
を使って書き直した例です。
pickup = ->(blog) { blog.favorites.length > 100 && blog.comments.length > 0 } Blogs.where(published: true).to_a.select(&pickup)
どうでしょうかselect
内の条件判定部分のロジックが抽出出来て読みやすくなっていますね👍
またlamda
を使うとメソッドやクラスに切り出しやすいのでリファクタリングもしやすいです👩🏭
メソッドの場合はlamda
の中のロジックを Blog
側のインスタンスメソッドに定義してあげるとインターフェースもほぼ変えずにリファクタリング出来ます。
Blogs.where(published: true).to_a.select(&:pickup?) class Blog def pickup?(user) blog.favorites.length > 100 && blog.comments.length > 0 end end
クラスの場合はこんな感じ。
Blogs.where(published: true).to_a.select{ |blog| BlogPickuper.call(blog) } class BlogPickuper def self.call(blog) blog.favorites.length > 100 && blog.comments.length > 0 end end
このようにメソッド切るほどじゃないけど少し複雑だったり名前をつけてあげたい場合にlamda
を使ってあげるとスッキリかけますし今後のリファクタリングもしやすくなりそうですね👍