From 64d2721cbad9c932ea8b1b51d46e32045232b611 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 23 Jul 2023 18:36:19 +0900 Subject: add slide --- README.md | 2 +- slide.pdf | Bin 134949 -> 237278 bytes slide.saty | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 389 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5bb5b4d..7ac7bed 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -https://phpstudy.connpass.com/event/TODO/ +https://phpstudy.connpass.com/event/290413/ diff --git a/slide.pdf b/slide.pdf index f566ab7..46d50ac 100644 Binary files a/slide.pdf and b/slide.pdf differ diff --git a/slide.saty b/slide.saty index dbed3ff..b691a29 100644 --- a/slide.saty +++ b/slide.saty @@ -5,6 +5,46 @@ @require: code-printer/code-theme @require: figbox/figbox +let-block +code-block-c source = + '< + +code-printer?:( + CodePrinter.make-config CodeSyntax.c CodeTheme.iceberg-light + |> CodePrinter.set-number-fun CodeDesign.number-fun-null + )(source); + > + +let-block +code-block-cpp source = + '< + +code-printer?:( + CodePrinter.make-config CodeSyntax.cpp CodeTheme.iceberg-light + |> CodePrinter.set-number-fun CodeDesign.number-fun-null + )(source); + > + +let-block +code-block-java source = + '< + +code-printer?:( + CodePrinter.make-config CodeSyntax.java CodeTheme.iceberg-light + |> CodePrinter.set-number-fun CodeDesign.number-fun-null + )(source); + > + +let-block +code-block-go source = + '< + +code-printer?:( + CodePrinter.make-config CodeSyntax.go CodeTheme.iceberg-light + |> CodePrinter.set-number-fun CodeDesign.number-fun-null + )(source); + > + +let-block +code-block-rust source = + '< + +code-printer?:( + CodePrinter.make-config CodeSyntax.rust CodeTheme.iceberg-light + |> CodePrinter.set-number-fun CodeDesign.number-fun-null + )(source); + > + let-block +code-block-php source = '< +code-printer?:( @@ -13,6 +53,13 @@ let-block +code-block-php source = )(source); > +let-inline \bad = { + \text-color(Color.rgb 0.75 0.25 0.25){Bad} + } +let-inline \good = { + \text-color(Color.rgb 0.1 0.5 0.1){Good} + } + open FigBox in @@ -24,10 +71,11 @@ document '< +make-title(| title = { - |TODO + |言語間で比較する + |エラーの通知と処理 |}; author = {|nsfisis (いまむら)|}; - date = {|第TODO回PHP勉強会@東京|}; + date = {|第154回PHP勉強会@東京|}; |); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -45,10 +93,346 @@ document '< ]); > + +frame{話すこと、話さないこと}< + +listing{ + * 話すこと + ** 様々な言語におけるエラー通知の方法 + * 話さないこと + ** 君たちはどう生きるか (PHP におけるベストプラクティス) + } + > + + +frame{取り上げる言語}< + +listing{ + * C + * C++ + * Java + * Go + * Rust + } + > + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +frame{まとめ}< - +p{TODO} + +section{|C|}< + +frame{C: 成功/失敗を戻り値で表す}< + +code-block-c(`#include + +bool do_something() { + // ... + if (success) { + return true; + } else { + return false; + } +} + `); + + +p{ + PHP では \inline-code(`mkdir()`); など + } + > + + +frame{C: 成功/失敗を戻り値で表す}< + +listing{ + * \bad; 処理結果があるときに使えない + * \bad; エラーに情報を載せられない + * \bad; エラーハンドリングを省略できる + ** \bad; 省略したとき、後続の処理が一切止まらない + } + > + + +frame{C: 引数で処理結果を受け取る}< + +code-block-c(`#include + +bool do_something(something* result) { + // ... + if (success) { + *result = ...; + return true; + } else { + return false; + } +} + `); + + +p{ + PHP では \inline-code(`preg_match()`); など + } + > + + +frame{C: 引数で処理結果を受け取る}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \bad; エラーハンドリングを省略できる + ** \good; 省略したとき、処理結果を使おうとすると止まる + ** \bad; 省略したとき、後続の処理が進みうる + } + > + + +frame{C: 処理結果または失敗を返す}< + +code-block-c(`something* do_something() { + // ... + if (success) { + return result; + } else { + return NULL; + } +} + `); + + +p{ + PHP では \inline-code(`fopen()`); など + } + > + + +frame{C: 処理結果または失敗を返す}< + +listing{ + * \good; 処理結果があるときに使える + * \bad; エラーに情報を載せられない + ** 注: 動的型付き言語の場合はその限りでない + * \bad; エラーハンドリングを省略できる + ** \good; 省略したとき、処理結果を使おうとすると止まる + ** \bad; 省略したとき、後続の処理が進みうる + } + > + + +frame{C: グローバル状態から通知する}< + +code-block-c(`some_error error; + +void do_something() { + // ... + if (success) { + error = 0; + } else { + error = 42; + } +} + +some_error get_error() { + return error; +} + `); + + +p{ + PHP では \inline-code(`json_decode()`); と \inline-code(`json_last_error()`); など + } + > + + +frame{C: グローバル状態から通知する}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \bad; エラーハンドリングを省略できる + ** \bad; 省略したとき、後続の処理が一切止まらない + } + > + > + + +section{|C++|}< + +frame{C++: 例外を投げる}< + +code-block-cpp(`#include + +void do_something() { + // ... + if (!success) { + throw std::runtime_error{"..."}; + } +} + `); + + +p{ + PHP では \inline-code(`DateTimeImmutable::__construct()`); など + } + > + + +frame{C++: 例外を投げる}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \bad; エラーハンドリングを省略できる + ** \good; 省略したとき、そこで止まる + } + > + > + + +section{|Java|}< + +frame{Java: 検査例外}< + +code-block-java(`void doSomething() throws SomeException { + // ... + if (!success) { + throw new SomeException(...); + } +} + `); + + +p{ + PHP では \inline-code(`@throws`); が (一応) 近い + } + > + + +frame{Java: 検査例外}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \good; エラーハンドリングを省略するとコンパイルエラーになる + ** \good; 省略ができない + } + > + + +frame{Java: 検査例外}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \good; エラーハンドリングを省略するとコンパイルエラーになる + ** \good; 省略ができない + * \bad; 大域脱出は処理の動きが複雑になる + * \bad; 例外クラスの継承ツリー設計が困難 + * \bad; 回復不能なエラーまで例外で表される + } + > + > + + +section{|Go|}< + +frame{Go: 多値返却}< + +code-block-go(`func doSomething() (int, error) { + // ... + if success { + return 42, nil + } else { + return 0, errors.New("...") + } +} + +result, err := doSomething() +if err != nil { + // ... +} + `); + > + + +frame{Go: 多値返却}< + +code-block-php(` + + +frame{Go: 多値返却}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \bad; エラーハンドリングを省略できる + ** \good; linter での検知は可能 + } + > + + +frame{Go: panic}< + +code-block-go(`func doSomething() int { + // ... + if !success { + panic("...") + } + return 42 +} + `); + + +p{ + 回復不能なエラー。(基本的には) 捕まえられない + } + > + + +frame{Go: 多値返却 + panic}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \bad; エラーハンドリングを省略できる + ** \good; linter での検知は可能 + * \good; 特殊な構文なし、大域脱出なし + * \good; エラー値のカテゴライズに継承が使われない + * \good; 回復可能なエラーと回復不能なエラーを区別できる + * \bad; 静的型付き言語以外だと、C と同レベルの安全性になる + } + > + > + + +section{|Rust|}< + +frame{Rust: 代数的データ型}< + +code-block-rust(`fn do_something() -> Result { + // ... + if success { + Ok(42) + } else { + Err(SomeError::new()) + } +} + `); + + +p{ + PHP では union 型が一番近い + } + > + + +frame{Rust: 代数的データ型 + panic}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \good; エラーハンドリングを省略するとコンパイルエラーになる + ** \good; 処理結果がない場合でも、linter での検知は可能 + * \good; 特殊な構文なし、大域脱出なし + * \good; エラー値のカテゴライズに継承が使われない + * \good; 回復可能なエラーと回復不能なエラーを区別できる + } + > + + +frame{Rust: 代数的データ型 + panic}< + +listing{ + * \good; 処理結果があるときに使える + * \good; エラーに情報を載せられる + * \good; エラーハンドリングを省略するとコンパイルエラーになる + ** \good; 処理結果がない場合でも、linter での検知は可能 + * \good; 特殊な構文なし、大域脱出なし + * \good; エラー値のカテゴライズに継承が使われない + * \good; 回復可能なエラーと回復不能なエラーを区別できる + * \bad; 静的型付き言語以外だと、C と同レベルの安全性になる + * \bad; 言語側にそれ相応のシンタックスシュガーがないと書きづらい + } + > + > + + +section{|PHP|}< + +frame{我らが PHP は...}< + +p{ + C 言語の素朴な値による通知と例外をミックスしたキメラ + } + +p{ + どう設計すべきかは今回のスコープ外 + } + > + + +frame{我らが PHP は...}< + +p{ + C 言語の素朴な値による通知と例外をミックスしたキメラ + } + +p{ + どう設計すべきかは今回のスコープ外 + } + +p{ + 君たちはどう生きるか + } + > > > -- cgit v1.2.3-70-g09d2