diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Dockerfile | 14 | ||||
| -rw-r--r-- | Makefile | 33 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | assets/me.jpeg | bin | 0 -> 10890 bytes | |||
| -rw-r--r-- | catchline.php | 62 | ||||
| -rw-r--r-- | slide.pdf | bin | 0 -> 233402 bytes | |||
| -rw-r--r-- | slide.saty | 288 | ||||
| -rw-r--r-- | test.sh | 6 |
9 files changed, 405 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19780ee --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/slide.satysfi-aux diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0cbb1ff --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM amutake/satysfi + +RUN opam update && \ + opam install satysfi-base + +RUN opam install satysfi-class-slydifi && \ + opam install satysfi-code-printer && \ + opam install satysfi-fonts-noto-sans && \ + opam install satysfi-fonts-noto-sans-cjk-jp + +RUN eval $(opam env) && \ + satyrographos install + +WORKDIR /work diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..34d193e --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +.PHONY: all +all: slide.pdf + +slide.pdf: slide.saty + docker run \ + -it \ + --rm \ + --name satysfi \ + --mount type=bind,src=$$(pwd),dst=/work \ + satysfi \ + satysfi slide.saty + +.PHONY: shell +shell: + docker run \ + -it \ + --rm \ + --name satysfi \ + --mount type=bind,src=$$(pwd),dst=/work \ + satysfi \ + sh + +.PHONY: docker +docker: + docker build --tag satysfi . + +.PHONY: clean +clean: + rm -f *.pdf *.satysfi-aux + +.PHONY: test +test: + @bash test.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..3be1b4d --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +https://phpstudy.doorkeeper.jp/events/151021 diff --git a/assets/me.jpeg b/assets/me.jpeg Binary files differnew file mode 100644 index 0000000..4e01020 --- /dev/null +++ b/assets/me.jpeg diff --git a/catchline.php b/catchline.php new file mode 100644 index 0000000..058abeb --- /dev/null +++ b/catchline.php @@ -0,0 +1,62 @@ +<?php +try { + f(3); +} catch (Throwable $e) { + while ($e = $e->getPrevious()) printf('%c', $e->getLine() + 23); + echo "\n"; +} +function f(int $i) { + if ($i < 0) f(); + try { + match ($i) { + 0 => X, // 12行目 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 => X, // 49行目 + + + + + + + + 1, 3 => X, // 57行目 + }; + } finally { + f($i - 1); + } +} diff --git a/slide.pdf b/slide.pdf Binary files differnew file mode 100644 index 0000000..5143243 --- /dev/null +++ b/slide.pdf diff --git a/slide.saty b/slide.saty new file mode 100644 index 0000000..b49fe48 --- /dev/null +++ b/slide.saty @@ -0,0 +1,288 @@ +@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 = `<?php +try { + f(3); +} catch (Throwable $e) { + while ($e = $e->getPrevious()) { + printf('%c', $e->getLine() + 23); + } + echo "\n"; +}` + +let catchline-fn-f = `function f(int $i) { + if ($i < 0) f(); + try { + match ($i) { + 0 => X, // 12行目 + // (間の空行は省略) + 2 => X, // 49行目 + // (間の空行は省略) + 1, 3 => X, // 57行目 + }; + } finally { + f($i - 1); + } +}` + +let catchline-fn-f-with-comments = `function f(int $i) { + if ($i < 0) f(); // エラー!引数が足りない! + try { + match ($i) { + 0 => X, // 12行目: エラー!未定義の定数! + // (間の空行は省略) + 2 => X, // 49行目: エラー!未定義の定数! + // (間の空行は省略) + 1, 3 => X, // 57行目: エラー!未定義の定数! + }; + } finally { + f($i - 1); + } +}` + +let catchline-fn-f-snip = `function f(int $i) { + if ($i < 0) f(); + try { + // ... + } finally { + f($i - 1); + } +}` + +let error-chain = `<?php +try { + try { + throw new \Exception("a"); + } finally { + throw new \Exception("b"); + } +} catch (\Exception $e) { + echo $e->getMessage(), PHP_EOL; // => b + echo $e->getPrevious()->getMessage(), PHP_EOL; // => a +}` + +open FigBox +in + +document '< + +make-title(| + title = { + |PHPerKaigi 2023 のトークン問題で + |ボツにした問題を供養する + |}; + author = {|nsfisis (いまむら)|}; + date = {|第149回PHP勉強会@東京|}; + |); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +frame{自己紹介}< + +fig-center(vconcat [ + hconcat [ + gap 20pt; + textbox{nsfisis (いまむら)}; + gap 20pt; + include-image 50pt `assets/me.jpeg`; + ]; + gap 20pt; + textbox{\@ デジタルサーカス株式会社}; + ]); + > + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +frame{PHPerKaigiとは}< + +fig-center(vconcat [ + gap 20pt; + textbox{2018年から開催されているPHPのカンファレンス}; + gap 20pt; + textbox{今年2023年も、3月23日から25日に開催}; + ]); + > + + +frame{PHPerチャレンジとは}< + +fig-center(vconcat [ + gap 20pt; + textbox{PHPerKaigiの企画の1つ}; + gap 20pt; + textbox{\inline-code(`#`);から始まる文字列(トークン)を、}; + textbox{公式サイトやスポンサーブログから探す}; + gap 10pt; + textbox{例: \inline-code(`#PHP`);}; + ]); + > + + +frame{トークン問題とは}< + +fig-center(vconcat [ + gap 20pt; + textbox{PHPerチャレンジのトークンを、PHPのソースコードに隠す}; + gap 20pt; + textbox{実行したり解読したりするとトークンが入手できる}; + ]); + > + + +frame{デジタルサーカスのトークン問題}< + +fig-center(vconcat [ + gap 20pt; + textbox{今年も問題を作成しました(全5問)}; + gap 20pt; + textbox{ボツ問になった問題のうちの1問を供養}; + ]); + > + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +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(`f(3)`);からスタート + } + > + + +frame{Catchline}< + +code-block-php(catchline-fn-f-snip); + +p{ + 1ずつ減らして、\inline-code(`$i`);が負なら引数なしで呼ぶ + } + > + + +frame{Catchline}< + +p{ + \listing{ + * \inline-code(`f(3)`); + * \inline-code(`f(2)`); + * \inline-code(`f(1)`); + * \inline-code(`f(0)`); + * \inline-code(`f(-1)`); + * \inline-code(`f()`); ここで終わり + } + } + > + + +frame{Catchline}< + +code-block-php(catchline-try); + +p{ + \inline-code(`\Throwable::getPrevious()`);を順に辿り、(エラーの発生した行数+23)を + } + +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{ + \listing{ + * エラー処理中に別のエラーが起きたとき、元々のエラーを保存する + * 内部利用しているライブラリが投げた例外クラスを、自分で定義した例外クラスでラップする + } + } + > + + +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{ + (エラーの発生した行数+23)をASCIIコードと見做して出力 + } + > + + +frame{Catchline}< + +code-block-php(catchline-fn-f-with-comments); + > + + +frame{Catchline}< + +p{ + \listing{ + * 12 + 23 = 35 (\inline-code(`#`);) + * 49 + 23 = 72 (\inline-code(`H`);) + * 57 + 23 = 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{みなさまの挑戦をお待ちしております!}; + ]); + > +> @@ -0,0 +1,6 @@ +if [[ ! "$(php catchline.php)" = "#PHP" ]]; then + echo Catchline >&2 + exit 1 +fi + +echo okay |
