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
prototype大全 / YAPC::Kyoto 2023
Search
utagawa kiki
March 19, 2023
Programming
1
4.3k
prototype大全 / YAPC::Kyoto 2023
サンプルコードはGitHubで公開しています
https://github.com/utgwkk/yapc-kyoto-2023-prototype
utagawa kiki
March 19, 2023
Tweet
Share
More Decks by utagawa kiki
See All by utagawa kiki
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
12k
Dive into gomock / Go Conference 2024
utgwkk
14
5k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
5
1.7k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
3k
ありがとう、create-react-app
utgwkk
4
10k
mockgenによるモック生成を高速化するツール bulkmockgenのご紹介 / Kyoto.go #43
utgwkk
2
2.2k
SPAでもデータをURLでシェアしたい / Kyoto.js 19
utgwkk
2
1.8k
なんでもPull Requestにする / Kichijoji.pm 31
utgwkk
3
6.2k
インプットとアウトプットのサイクルを回す暮らし / Kichijoji.pm 29
utgwkk
1
9k
Other Decks in Programming
See All in Programming
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
4
1.5k
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
230
OSSで起業してもうすぐ10年 / Open Source Conference 2024 Shimane
furukawayasuto
0
110
Quine, Polyglot, 良いコード
qnighy
4
650
Jakarta EE meets AI
ivargrimstad
0
130
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
340
Duckdb-Wasmでローカルダッシュボードを作ってみた
nkforwork
0
130
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
120
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.8k
Featured
See All Featured
Ruby is Unlike a Banana
tanoku
97
11k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Designing Experiences People Love
moore
138
23k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Visualization
eitanlees
145
15k
RailsConf 2023
tenderlove
29
900
Done Done
chrislema
181
16k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Being A Developer After 40
akosma
87
590k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
Transcript
prototype大全 YAPC::Kyoto 2023 @utgwkk (うたがわきき)
自己紹介 @utgwkk (うたがわきき) 株式会社はてな Webアプリケーションエンジニア in 京都 最近は主にGoを書いて暮らしています
突然ですがこちらのコードをご覧ください (1) push @arr, "new value"; map { $_ +
2 } @arr; try { everything() } catch { up() };
突然ですがこちらのコードをご覧ください (2) push @arr, "new value"; # なんでこれでpushできるの? map {
$_ + 2 } @arr; # { } の中は何? try { everything() } catch { up() }; # try-catchだ!!1 →prototypeが関係している
今日の目標 (1) push @arr, "new value"; map { $_ +
2 } @arr; try { everything() } catch { up() }; これらの裏で起こっていることからprototypeを読み解く
今日の目標 (2) ↓のサブルーチン定義 (prototype) の意味が分かるようになる sub foo ($) { }
sub bar ($;$@) { } sub mymap (&@) { } sub zip (\@\@) { } sub foo () { 1 }
try-catchから始めるprototype入門
prototypeとは とても限られた形のコンパイル時引数チェック サブルーチンの引数の解釈方法を制御できる パーサーの挙動が変わる!! (表現力が上がる) メソッドにはprototypeを指定できない
prototypeの書き方 (1) sub name (prototype) { ... } サブルーチン定義の後ろに括弧で書く sub
name :prototype(prototype) { ... } attributeを使うこともできる (subroutine signaturesと衝突しない)
prototypeの書き方 (2) sub name (prototype) { ... } ← この発表ではこっちを使う
サブルーチン定義の後ろに括弧で書く sub name :prototype(prototype) { ... } attributeを使うこともできる (subroutine signaturesと衝突しない)
prototypeに出てくる記号 シジル (変数につける記号) に対応すると考えるとよさそう $はscalar, @はlist, %はhash, &はサブルーチン, *はglob \を付けるとリファレンスになる
\[] で囲むといずれか1つのリファレンス (バックスラッシュが必要) ; 以降は省略可能
prototypeの例 sub foo ($) { } sub bar ($;$@) {
} sub mymap (&@) { } sub zip (\@\@) { } sub foo () { 1 }
prototypeの読み方 (再掲) sub foo ($) { } # 括弧の中に記号を書く sub
bar ($;$@) { } # ; 以降は省略可能 sub mymap (&@) { } # &はサブルーチン、@はリスト sub zip (\@\@) { } # リストをリファレンスとして受ける sub foo () { 1 } # 定数をreturnなしで返する
prototypeに書けるもの だいたいなんでも書けてすごい だいたいなんでも書けるけどwarningされる sub f (hello!!1) { } # prototypeは
hello!!1 sub g (こんにちは) { } # prototypeは こんにちは なんでだいたいなんでも書けるのかは不明 (知ってたら教えてください)
prototypeの例 (Try::Tiny) try-catch構文をprototypeで再現 https://metacpan.org/pod/Try::Tiny try { } catch { }
finally { }; 最近のPerlにはtry-catch構文が組み込まれている
Try::Tinyのコードを読んでいく (1) sub try(&;@) try-catch構文のスタート コードブロック (無名サブルーチン) を受け取る 省略せずに書くと try(sub
{ }, ...) 例外が送出されたらcatch/finallyブロックの処理が実行される
Try::Tinyのコードを読んでいく (2) sub catch(&;@) 例外を捕捉する ブロック内では $_ 変数に例外の内容が入っている 省略せずに書くと catch(sub
{ }, ...) Try::Tiny::Catch packageでblessしているけど実体は無名サブルーチン
Try::Tinyのコードを読んでいく (3) sub finally(&;@) try-catchの最後に必ず呼ばれる finallyブロックの処理はTry::Tiny::ScopeGuard packageでblessされる
Try::Tinyのコードを読んでいく (まとめ) try { } catch { } finally {
}; try(sub { }, catch(sub { }, finally(sub { }))); 単なるサブルーチン呼び出し式なので、ブロックの後ろに ; が必要 ブロックではなく無名サブルーチンなのでreturnしても関数全体を抜けない (罠)
ちなみに別のtry-catchは? Syntax::Keyword::Try syntax pluginという仕組みでtry-catch構文を再現 (セミコロン不要) 詳細は以下の記事など Syntax::Keyword::TryとPerlのキーワードプラグイン (その1) - Masteries
最近のPerlにはtry-catch構文が組み込まれている (再掲)
prototypeについて網羅的に知るには (1) perldoc perlsubにまとまっている 今回解説しきれていない項目もあります https://perldoc.perl.org/perlsub#Prototypes https://perldoc.jp/docs/perl/5.36.0/perlsub.pod#Prototypes
prototypeについて網羅的に知るには (2) prototypeを使ってtry-catch構文を再現する例がperldoc perlsubに書いてある!!
こんなにあるぞ!! prototype
こんなにあるぞ!! prototype prototypeによって得られている効能についてご紹介します
リストにpushするには push @arr, @elems; sub mypush(\@@) 第1引数はリストのリファレンスを受け取る 第2引数以降はリストとして解釈される 第1引数のリストに破壊的変更を加えることができる
mapの正体 map { $_ + 2 } @arr; ブロックだと思っているのは無名サブルーチン ブロック内でreturnしてもサブルーチン全体から抜けるわけではない
紛らわしいのでブロックに渡すサブルーチンを用意するのがよさそう
定数展開 sub a1 () { "aaa" } say a1 .
"bbb"; コンパイル時に say "aaabbb" に展開される use constantしたときと似たような効能が得られる sub a2 { "aaa" } だと展開されない https://perldoc.perl.org/perlsub#Constant-Functions
身近に潜むprototype採用事例 (Test2::V0) is $obj, object { prop isa => 'Foo';
call meth => 'blah'; }; $obj の性質を宣言的にテストできる ちなみにTest::Deepだと↓のように書ける cmp_deeply $obj, isa('Foo') & methods(meth => 'blah);
身近に潜むprototype採用事例 (Module::Find) usesub Foo::Plugin; indirectだと思って読むと Foo::Plugin->usesub になるのでは? sub usesub(*) {
… } barewordを受け取ってパッケージ名だと解釈できる
身近に潜むprototype採用事例 (Scope::Guard) my $g = guard { }; 変数 $g
のスコープが終わったらブロックに渡した処理が呼ばれる これも無名サブルーチン スコープが終わったらDESTROYメソッドが呼ばれる 最近のPerlだとdeferがある (experimental)
身近に潜むprototype採用事例 (List::MoreUtils) (1) zip6 @xs, @ys, @zs; 6はPerl6 (現Raku) の6
別名zip_unflatten [$xs[0], $ys[0], $zs[0]], [$xs[1], $ys[1], $zs[1]], ... のリストを返す
身近に潜むprototype採用事例 (List::MoreUtils) (2) ところで say @xs, @ys, @zs ってやったらリストが平坦になるのでは? zip6
@xs, @ys, @zs では各リストはリファレンスとして渡されている リファレンスなら平坦になることはない % perl -E '@xs = (1, 2); @ys = (3, 4); @zs = (5, 6); say @xs, @ys, @zs' 123456
身近に潜むprototype採用事例 (List::MoreUtils) (3) sub zip6 (\@\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\ @\@\@\@\@) \@ が32個!! 一番好きなprototypeです
リストを33個渡すとコンパイルエラーになる (無限に渡せない) https://metacpan.org/release/REHSACK/List-MoreUtils-0.430/source/lib/List/More Utils/PP.pm#L520
身近に潜むprototype採用事例 (List::MoreUtils) (4) 実際にリストを33個渡してみましょう…… (ここでデモ)
身近に潜むprototype採用事例 (List::MoreUtils) (5) % carmel exec perl 02-list-moreutils-zip6.pl Too many
arguments for List::MoreUtils::XS::zip6 at 02-list-moreutils-zip6.pl line 16, near ")" Execution of 02-list-moreutils-zip6.pl aborted due to compilation errors.
身近に潜むprototype採用事例 (ほかいろいろ) きっと無限にprototype採用事例があるはず!! 心当たりがある方はTwitterとかでシェアーしてください
気になるあのサブルーチンのprototype、 コッソリ教えます
prototypeサブルーチン https://perldoc.perl.org/functions/prototype サブルーチンのprototypeを文字列として返す 組み込みサブルーチンのprototypeはうまく取得できないことがある (mapとか)
組み込みサブルーチンのprototype 実はperldoc perlsubに例示されている (全てではない) https://perldoc.perl.org/perlsub#Prototypes
実装を読みにいったほうが早い説 サブルーチン定義をがんばって探す XSなら PROTOTYPE: に書いてある けどREPLとかでサクッと見れるのはよいと思う
Deparseすると何が起こっているのか分かる説 perl -MO=Deparse は友達 どのように構文解析されたのかが分かる コンパイラの気持ちを知れば何が起こっているのかが分かるかも
prototypeを使う/使わない理由
prototypeを使う理由 DSL的に書きたい かっこよく書けるとかっこいい subって書きたくない あわよくばコンパイラの最適化を効かせたい
prototypeを使わない理由 ブロックのつもりで書いても無名関数になる 最近のPerlにはtry-catch構文が入っている なんでもprototypeを使えばよいというものではない (銀の弾丸ではない) use constantでよくない??
おさらい 読めるようになりましたね? sub foo ($) { } sub bar ($;$@)
{ } sub mymap (&@) { } sub zip (\@\@) { } sub foo () { 1 }
おわり prototypeによってPerlコードの表現力が広がる とはいえprototypeを濫用すればするほどよいというものではない 用法用量を守って楽しいprototypeライフを送りましょう { } は無名サブルーチンだというのを忘れずにいると罠を回避できるかも?
参考文献 • https://perldoc.perl.org/perlsub • https://perldoc.jp/docs/perl/5.36.0/perlsub.pod#Prototypes • https://metacpan.org/pod/Try::Tiny • https://papix.hatenablog.com/entry/2019/12/02/170611 •
https://metacpan.org/pod/Test2::V0 • https://metacpan.org/pod/List::MoreUtils • https://metacpan.org/pod/Scope::Guard • https://perldoc.perl.org/functions/prototype
サンプルコード https://github.com/utgwkk/yapc-kyoto-2023-prototype で公開しています