Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
pickpatch を作った話と仕組みの解説
Search
KoharaKazuya
June 14, 2019
62
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
pickpatch を作った話と仕組みの解説
ランチタイム勉強会 2019-06-14
KoharaKazuya
June 14, 2019
More Decks by KoharaKazuya
See All by KoharaKazuya
Native File System API の紹介と Zip を作る Web サービスを作った話
koharakazuya
0
200
グラフィカルに URL を編集できるサービスを作った
koharakazuya
1
16k
Go でのエラー生成パターン
koharakazuya
0
17k
Featured
See All Featured
Music & Morning Musume
bryan
48
7.4k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
Building Applications with DynamoDB
mza
96
7.2k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
320
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
840
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Statistics for Hackers
jakevdp
799
230k
From π to Pie charts
rasagy
1
390
Transcript
pickpatch を作った話と仕組み の解説 ランチタイム勉強会
今日話すこと set("a.b", 10) のようなダサい API をやめるライブラリを書 いた ‑ Qiita pickpatch
の技術解説 (個人的に会心のアイデアだったので事あるごとに自慢してる 話) 2 2
自己紹介 小原 一哉 (こはら かず や) ウェブエンジニア フェンリル株式会社 @KoharaKazuya 3
3
背景 ネストの深いオブジェクトの一部分を簡単に更新したい const app = { title: "pickpatch", authors: [
{ age: 29, name: "Kohara Kazuya" } ] }; 4 4
既存の手法 代入 (破壊的変更、mutation) Underscore.js, Lodash Immer 5 5
代入 app.authors[0].name = " 小原 一哉"; 当然一番手軽で安定した方法。 (Redux の台頭など、詳細は割愛するが) Immutable
がいい場合は使えない。 6 6
Underscore.js, Lodash const replaced = _.set(app, "authors[0].name", " 小原 一哉");
文字列でアクセス。 静的解析と相性が悪い。TypeScript の台頭で露見してきた。 7 7
Immer const replaced = produce(app, draft => { draft.authors[0].name =
" 小原 一哉"; }); マジカルになんとかしちゃう。 書く側は代入と一緒だが、裏では一部を置き換えつつ 新しいオブジェクトを作っている。 8 8
Immer すごい 9 9
Immer の仕組み ES2015 Proxy を用いて実現している。 Proxy: オブジェクトへのアクセス、操作、命令を インターセプトできるやつ。 名前の通りプロキシのイメージ 10
10
Immer いいけど、そもそも代入っぽいこともしたくないんや。 const replaced = produce(app, draft => { draft.authors[0].name
= " 小原 一哉"; // ↑ ここが生理的に無理なんや }); 11 11
アイデア 値の更新とは新しい値の宣言 (reduce など) 更新したい部分の宣言と遷移の処理は分離できる 部分の宣言は . によるチェーンがもっとも自然 12 12
pickpatch を作った const obj = { a: { b: 1
}, c: 2, d: 3 }; const newObj = pickpatch( _ => [_.a.b, _.c], // picker defines partial to update )( ([b, c]) => [b * 10, c + 5], // patcher defines new values )( obj, // old object ); // -> { a: { b: 10 }, c: 7, d: 3 } 13 13
pickpatch の仕組み (一ファイルの数十行のソースだがやたら難しい) picker と patcher と更新対象を引数にとる Immer と同じく Proxy
を使ってマジカルなことをする 14 14
picker 更新対象から更新する部分を宣言させる関数 const picker = app => app.authors[0].name; ユーザーは 「更新対象の全体が引数として与えられて、
更新する部分を返す関数」 を定義する 15 15
picker 実際は picker の引数には Proxy が仕掛けられた ダミーのオブジェクトを渡している const picker =
app => app.authors[0].name; picker の戻り値にはプロパティアクセスの キーが記録されている 16 16
patcher 更新のロジックを定義する関数 const patcher = old => " 小原 一哉";
ユーザーは 「picker で選択した値が引数として与えられて、 その部分の新しい値を返す関数」 を定義する 17 17
patcher picker のプロパティアクセスのキーの情報を元に、 更新対象から値を抽出し、引数に与える。 const patcher = old => "
小原 一哉"; 返り値を更新の際に用いる。 更新対象の一部を置き換えた新しいオブジェクトを生成する。 18 18
Type Inference Fiendly 型定義はユーザーのメンタルモデルに合わせている ≠ 真実の型 → TypeScript でしっかり型チェックが効く 19
19
関連 後から知ったんだけど、類似の実装として Haskell Lens というものがあるらしい……。 読もうとして撃沈しました。 多分ユーザーのメンタルモデルは同じ。 20 20
まとめ pickpatch を作った Proxy を使ってマジカルなことができる 部分の宣言と更新ロジックの分離 Haskell Lens というのもあるらしい 21
21