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.7k
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
現役スタートアップCTOが解説する、ソフトウェア開発という仕事の理論・実践・キャリア
fujimura
0
56
庭と負債
fujimura
4
2.3k
AIの時代で我々はどのようにコードを書くのか
fujimura
4
1k
SaaSを作るという仕事について
fujimura
13
6.3k
一文字エイリアスのすすめ
fujimura
0
450
現役CTOが語る!RubyKaigiの楽しみ方
fujimura
0
1.3k
いかにして文系新卒エンジニアが「大きな問い」を大事にするCTOになったのか
fujimura
2
750
Kaigi on Rails 2022 - 既存Railsアプリ攻略法 CTOが見ること・やること・考えること
fujimura
14
5.2k
入門 名前
fujimura
25
14k
Other Decks in Programming
See All in Programming
MLH State of the League: 2026 Season
theycallmeswift
0
220
Design Foundational Data Engineering Observability
sucitw
3
160
🔨 小さなビルドシステムを作る
momeemt
3
660
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
4
1.9k
オープンセミナー2025@広島「君はどこで動かすか?」アンケート結果
satoshi256kbyte
0
240
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
140
速いWebフレームワークを作る
yusukebe
5
1.7k
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
210
Testing Trophyは叫ばない
toms74209200
0
660
Rancher と Terraform
fufuhu
2
200
UbieのAIパートナーを支えるコンテキストエンジニアリング実践
syucream
2
820
Protocol Buffersの型を超えて拡張性を得る / Beyond Protocol Buffers Types Achieving Extensibility
linyows
0
110
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
Optimizing for Happiness
mojombo
379
70k
Rebuilding a faster, lazier Slack
samanthasiow
83
9.2k
A better future with KSS
kneath
239
17k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
111
20k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
BBQ
matthewcrist
89
9.8k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
139
34k
Side Projects
sachag
455
43k
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との違いは?わからん!誰か教えてくれ!