aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile14
-rw-r--r--Makefile33
-rw-r--r--README.md1
-rw-r--r--assets/me.jpegbin0 -> 10890 bytes
-rw-r--r--catchline.php62
-rw-r--r--slide.pdfbin0 -> 233402 bytes
-rw-r--r--slide.saty288
-rw-r--r--test.sh6
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
new file mode 100644
index 0000000..4e01020
--- /dev/null
+++ b/assets/me.jpeg
Binary files differ
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
new file mode 100644
index 0000000..5143243
--- /dev/null
+++ b/slide.pdf
Binary files differ
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{みなさまの挑戦をお待ちしております!};
+ ]);
+ >
+>
diff --git a/test.sh b/test.sh
new file mode 100644
index 0000000..7989b50
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,6 @@
+if [[ ! "$(php catchline.php)" = "#PHP" ]]; then
+ echo Catchline >&2
+ exit 1
+fi
+
+echo okay