@require: class-slydifi/theme/akasaka @require: code-printer/code-design @require: code-printer/code-printer @require: code-printer/code-syntax @require: code-printer/code-theme @require: figbox/figbox let-block +code-block source keywords = let syntax = let void-syntax-rule = CodePrinter.syntax-rule-fun (fun _ -> None) in CodePrinter.make-syntax (| line-comment = void-syntax-rule; block-comment = void-syntax-rule; string = void-syntax-rule; keywords = keywords; identifier = void-syntax-rule; others = []; |) in '< +code-printer?:( CodePrinter.make-config syntax CodeTheme.iceberg-light |> CodePrinter.set-number-fun CodeDesign.number-fun-null )(source); > let-block +code-block-php source = '< +code-printer?:( CodePrinter.make-config CodeSyntax.php CodeTheme.iceberg-light |> CodePrinter.set-number-fun CodeDesign.number-fun-null )(source); > let catchline-try = `getLine() + 21); } while ($e = $e->getPrevious()); echo "\n"; }` let catchline-fn-f = `function f(int $i) { if ($i < 0) return; try { match ($i) { 0 => X, // 14行目 // (間の空行は省略) 2 => X, // 51行目 // (間の空行は省略) 1, 3 => X, // 59行目 }; } finally { f($i - 1); } }` let catchline-fn-f-with-comments = `function f(int $i) { if ($i < 0) return; try { match ($i) { 0 => X, // 14行目: エラー!未定義の定数! // (間の空行は省略) 2 => X, // 51行目: エラー!未定義の定数! // (間の空行は省略) 1, 3 => X, // 59行目: エラー!未定義の定数! }; } finally { f($i - 1); } }` let error-chain = ` %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +frame{PHPerKaigiとは、トークン問題とは}< +fig-center(vconcat [ gap 20pt; textbox{時間がないので省略。長谷川さんに聞いてください}; gap 20pt; textbox{変わったPHPプログラムを持ってきたので解説します}; ]); > %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +frame{Catchline}< +code-block-php(catchline-try); > +frame{Catchline}< +code-block-php(catchline-fn-f); > +frame{Catchline}< +code-block-php(catchline-try); +p{ \inline-code(`f()`);を呼び出して\inline-code(`Throwable`);を捕まえ、何かする } > +frame{Catchline}< +code-block-php(catchline-fn-f-with-comments); > +frame{Catchline}< +code-block-php(catchline-try); +p{ \inline-code(`\Throwable::getPrevious()`);を順に辿り、(エラーの発生した行数+21)を } +p{ ASCIIコード\text-color(Color.gray(0.75)){[1]}と見做して出力 } +p{ \text-color(Color.gray(0.75)){[1]: VAS Syndrome} } > +frame{Catchline}< +p{ \inline-code(`\Throwable::getPrevious()`); } +p{ 発生したエラーの1つ前のエラー(=大本の原因) } +p{ 通常は例外クラスのコンストラクタに渡して設定する } > +frame{Catchline}< +code-block-php(error-chain); +p{ \inline-code(`finally`);節の中で例外を発生させると、PHPの処理系が勝手に`$previous`を設定する } > +frame{Catchline}< +code-block-php(catchline-fn-f-with-comments); > +frame{Catchline}< +code-block-php(catchline-try); +p{ (エラーの発生した行数+21)をASCIIコードと見做して出力 } > +frame{Catchline}< +code-block-php(catchline-fn-f-with-comments); > +frame{Catchline}< +p{ \listing{ * 14 + 21 = 35 (\inline-code(`#`);) * 51 + 21 = 72 (\inline-code(`H`);) * 59 + 21 = 80 (\inline-code(`P`);) } } +p{ 組み合わせて\inline-code(`#PHP`);に } > %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +frame{おわりに}< +fig-center(vconcat ?:(align-center) [ gap 20pt; textbox{来たる3月のPHPerKaigi 2023で}; gap 20pt; textbox{これより数段凝った問題を5つ出題します!}; gap 20pt; textbox{みなさまの挑戦をお待ちしております!}; ]); > >