Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SimpleDelegator活用のご提案
Search
Fujimura Daisuke
December 14, 2019
Programming
0
1.5k
SimpleDelegator活用のご提案
平成Ruby会議 01
https://github.com/fujimura/heisei_ruby_kaigi_01_simple_delegator
Fujimura Daisuke
December 14, 2019
Tweet
Share
More Decks by Fujimura Daisuke
See All by Fujimura Daisuke
庭と負債
fujimura
4
1.1k
AIの時代で我々はどのようにコードを書くのか
fujimura
3
850
SaaSを作るという仕事について
fujimura
12
5.7k
一文字エイリアスのすすめ
fujimura
0
330
現役CTOが語る!RubyKaigiの楽しみ方
fujimura
0
1.2k
いかにして文系新卒エンジニアが「大きな問い」を大事にするCTOになったのか
fujimura
2
670
Kaigi on Rails 2022 - 既存Railsアプリ攻略法 CTOが見ること・やること・考えること
fujimura
14
3.9k
入門 名前
fujimura
24
14k
それPostgreSQLでできるよ @ Rails Developer Meetup 2018 Day 1
fujimura
10
3.9k
Other Decks in Programming
See All in Programming
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
180
From Translations to Multi Dimension Entities
alexanderschranz
2
130
return文におけるstd::moveについて
onihusube
1
730
CSC305 Lecture 26
javiergs
PRO
0
140
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
630
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
130
事業成長を爆速で進めてきたプロダクトエンジニアたちの成功談・失敗談
nealle
3
1.4k
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
190
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
17年周年のWebアプリケーションにTanStack Queryを導入する / Implementing TanStack Query in a 17th Anniversary Web Application
saitolume
0
250
선언형 UI에서의 상태관리
l2hyunwoo
0
140
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Building Adaptive Systems
keathley
38
2.3k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
440
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Producing Creativity
orderedlist
PRO
341
39k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
25k
Transcript
SimpleDelegator 活⽤のご提案 平成Ruby会議 01 Daisuke Fujimura 2019-12-14
⾃⼰紹介 藤村⼤介 https://twitter.com/ffu_ https://github.com/fujimura スタートアップ数社 ⇨ マチマチCTO ⇨ フリーランス Ruby歴11年
現在は数社で技術顧問のお仕事 最近はPythonとYAMLを書いている WEB+DB PRESS Vol.110 名前付け⼤全を書いた
今⽇のお話 SimpleDelegatorは便利なのにあまり使われていない印象があるので宣伝したい!
SimpleDelegator とは オブジェクト指向でいうところの「委譲」ができるライブラリ Ruby標準ライブラリ ‘delegate’ に含まれる
基本的な使⽤例 出典: https://ruby-doc.org/stdlib-2.6.5/libdoc/delegate/rdoc/SimpleDelegator.html class User def born_on Date.new(1989, 9, 10)
end end class UserDecorator < SimpleDelegator def birth_year born_on.year end end decorated_user = UserDecorator.new(User.new) decorated_user.birth_year #=> 1989 decorated_user.__getobj__ #=> #<User: ...>
何が便利なの 局所的な振る舞いを後から追加することができる 部分的にしか使わない実装で元のクラスを膨らませないで済む デコレーターを簡単に書ける その他、⼩技がいくつか
具体例
例:インターフェイスを揃えたい 既存のオブジェクトのインターフェイスが期待しているものと異なる APIのレスポンスがオブジェクトで、モデルとインターフェイスが違うケース 簡単にデコレーターを書けました class Entry < SimpleDelegator def title
subject end end entries = api.get('/entries/').map { |r| Entry.new(r) } puts entries.first.title # => `subject` の値
例:ソート順を変えたい 特定の箇所で既存のオブジェクトのソート順を変えたい デコレーターはインターフェイスだけでなく挙動を拡張することもできます class UserSortedByBirthday < SimpleDelegator def <=>(other) birthday
> other.birthday end end users = User.limit(10).map {|u| UserSortedByBirthday.new(u) } users.sort #=> 誕⽣⽇で並べ替えられる
例:アクセサを⾜したい 元のクラスにアクセサは定義したくない クラスを読み下していって「これのアクセサは⼀体…?」となりがち 後にそのアクセサが悪⽤されて副作⽤パズルが発⽣したりするけど、これなら防げる 局所化は最⾼ class UserWithToken < SimpleDelegator attr_accessor
:token end token = generate_token users = User.limit(10).map {|user| u = UserWithTimestamp.new(user) u.token = token u } users.first.token #=> ⽣成したトークン
例:現在のユーザーによってオブジェクトの値を 変えたい オブジェクトの振る舞いを他のオブジェクトによって変えたい post に状態をもたせる実装よりも影響範囲が少ない Post#comments_for(user) という実装も考えられるけど、パーソナライズする 箇所が増えるといちいち渡すのが⾯倒 局所化は最⾼ class
PersonalizedPost < SimpleDelegator def initialize(post, user) @user = user __setobj__(post) end def comments __getobj__.comments.filter {|c| !c.author.blocked_by?(@user) } end end posts = Post.first(10).map {|p| PersonalizedPost.new(p, current_user) } posts.first.comments # ブロックされたユーザーのコメントは現れない
例:クエリオブジェクト作るの⾯倒 これは完全に⼩技 DailyNewCommentQuery.new(...).result というようなクエリオブジェクトあ るある実装より簡潔 class DailyNewComment < SimpleDelegator def
initialize(user, start_at) comments = user.visible_comments.where( 'created_at >= :from AND created_at < :to', from: start_at, to: 24.hours.since(start_at) ) __setobj__(comments) end end comments = DailyNewComment.new(user, start_at)
まとめ SimpleDelegatorは便利 局所化進めていきましょう
補⾜ 遅いってマジ? DelegateClassとの違いは?わからん!誰か教えてくれ!