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
63
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
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
430
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.6k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
670
The World Runs on Bad Software
bkeepers
PRO
72
12k
A Soul's Torment
seathinner
8
3.9k
BBQ
matthewcrist
90
10k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.7k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
350
How to train your dragon (web standard)
notwaldorf
96
6.9k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
540
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
370
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