From db3d51ddc421dad68abddb95d01ffdab440197d6 Mon Sep 17 00:00:00 2001
From: nsfisis
2021-03-26 から 2021-03-28 にかけて開催された、 PHPerKaigi 2021 に一般参加者として参加した。 弊社 デジタルサーカス株式会社 (今年1月から勤務) はダイヤモンドスポンサーとなっており、スポンサー枠のチケットを使わせていただいた。
-
@@ -126,7 +126,7 @@
をいただいた。
-
+
+
-
+
+
-
- PHPerKaigi 2021 参加レポ
+ PHPerKaigi 2021 参加レポ
発表・スライドのメモ (引用ではない) @@ -86,10 +86,10 @@
PHP で AWS Lambda
@@ -155,8 +155,8 @@大規模サイトの SEO
@@ -222,8 +222,8 @@知覚可能 操作可能 理解可能 堅牢 ちゃんとしたHTMLを書く (閉じタグ・入れ子構造など) @@ -314,8 +314,8 @@
PHP で FUSE
@@ -406,10 +406,10 @@ATDD
@@ -556,8 +556,8 @@型解析を用いたリファクタリング
@@ -611,15 +611,15 @@昼食をとっていた。事前に何か食料を買っておくべきだった。
Documentation as Code
@@ -691,8 +691,8 @@cookie による session 管理
@@ -702,8 +702,8 @@PHP のエラーと例外
@@ -842,8 +842,8 @@Laravel のメール認証
@@ -853,8 +853,8 @@gRPC
@@ -918,8 +918,8 @@アーキテクチャテスト
@@ -978,8 +978,8 @@冒頭に書いた通り、2日目から体調が悪くまともに聴けていない。途中までは頭痛を我慢しつつ見ていたのだが、まともに入ってこなかった。
@@ -989,8 +989,8 @@Day 2 にほとんど参加できなかったのは残念だが、イベント自体は大変楽しく、また興味深いものであった。自分がまったく知らない領域の話を聞けるのはこうしたイベントならではだと感じる。オンライン開催ゆえ現地に行く必要がなく、気軽に参加できたのも (特に初参加者として) 嬉しいポイントだった。
diff --git a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html index 097d417..ba31a99 100644 --- a/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html +++ b/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html @@ -65,15 +65,15 @@ -
case - in によるパターンマッチング構文でも、case - when と同じように then が使える (場合によっては使う必要がある)。
then とはthen とは
使われることは稀だが、Ruby では then がキーワードになっている。次のように使う:
普通 Ruby のコードで then を書くことはない。なぜか。次のコードを実行してみるとわかる。
then や ; や改行が必要かthen や ; や改行が必要か
なぜ then や ; や改行 (以下 「then 等」) が必要なのだろうか。次の例を見てほしい:
case - in における thencase - in における then
ようやく本題にたどり着いた。来る Ruby 3.0 では case と in キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして then 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。
if や case の条件の後ろには then、;、改行のいずれかが必要
diff --git a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
index 9e77a85..8c6e269 100644
--- a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
+++ b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
@@ -62,8 +62,8 @@
- Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。
@@ -100,8 +100,8 @@調査に使用したソース (調査時点での最新 master)
@@ -242,8 +242,8 @@ rustc_resolve/src/lib.rs: table.insert(sym::i128, Int(IntTy::I128));Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。
diff --git a/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html b/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html index 44ee689..b9455f7 100644 --- a/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html +++ b/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html @@ -62,15 +62,15 @@ -違いはない。ただのエイリアス。
Vim の autocmd events には似通った名前のものがいくつかある。大抵は :help に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。
以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。
@@ -139,8 +139,8 @@ {"BufWritePre", EVENT_BUFWRITEPRE},
neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり aliases と書かれている。
FileEncoding だが、これは :help FileEncoding にしっかりと書いてある。
- *FileEncoding*
- FileEncoding Obsolete. It still works and is equivalent
+ *FileEncoding*
+FileEncoding Obsolete. It still works and is equivalent
to |EncodingChanged|.
+ 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。 +
-- 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。 -
+BufAdd/BufCreate
+ BufCreate は歴史的な理由により ("for historic reasons") 存在しているため、新しい方 (BufAdd) を使う
+ BufAdd/BufCreate
- BufCreate は歴史的な理由により ("for historic reasons") 存在しているため、新しい方 (BufAdd) を使う
- BufRead/BufReadPost
- BufReadPre との対称性のため、あるいは BufWritePost との対称性のため BufReadPost を使う
- BufWrite/BufWritePre
- BufWritePost との対称性のため、あるいは BufReadPre との対称性のため BufWritePre を使う
- FileEncoding/EncodingChanged
- FileEncoding は `Obsolete'' と明言されているので、`EncodingChanged を使う
- BufRead/BufReadPost
+ BufReadPre との対称性のため、あるいは BufWritePost との対称性のため BufReadPost を使う
+
- ところでこの調査で知ったのだが、BufRead と BufWrite は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら Pre/Post 付きのものを使った方が分かりやすいだろう。
-
BufWrite/BufWritePre
+ BufWritePost との対称性のため、あるいは BufReadPre との対称性のため BufWritePre を使う
+ FileEncoding/EncodingChanged
+ FileEncoding は `Obsolete'' と明言されているので、`EncodingChanged を使う
+
+ ところでこの調査で知ったのだが、BufRead と BufWrite は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら Pre/Post 付きのものを使った方が分かりやすいだろう。
+
" License: Public Domain
+
+command! -bar -range=%
+ \ Reverse
+ \ keeppatterns <line1>,<line2>g/^/m<line1>-1
+
:version の一部
tac / tailtac / tail
tac や tail -r などの外部コマンドを ! を使って呼び出し、置き換える。
:g/^/m0:g/^/m0
こちらは外部コマンドに頼らず、Vim の機能のみを使う。g は :global コマンドの、m は :move コマンドの略
:g/^/m0 の問題点:g/^/m0 の問題点
:global コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。^ は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。'hlsearch' オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと n コマンドなどの際に不便である。
[2020/9/28追記] より簡潔な方法を見つけたので次節に追記した @@ -212,8 +221,8 @@ command! -bar -range=%
[2020/9/28追記] より簡潔な方法を見つけたため追記する @@ -234,15 +243,6 @@ command! -bar -range=%
" License: Public Domain
-
-command! -bar -range=%
- \ Reverse
- \ keeppatterns <line1>,<line2>g/^/m<line1>-1
- ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。
@@ -153,17 +153,17 @@ $🐘([ この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。 -まず目につくのは大量の絵文字だろう。 PHP は識別子に使用できる文字の範囲が広く、絵文字も使うことができる。
Brainf*ck のインタプリタとプログラムになっている。 Brainf*ck とは、難解プログラミング言語のひとつであり、ここで説明するよりも Wikipedia の該当ページを読んだ方がよい。
@@ -246,22 +246,22 @@ $🐘([
おおよそ意味に合致するよう選んでいるが、$🤡 と $🎪 は弊社デジタルサーカスにちなんでいる。 また、$🐘 は PHP のマスコットの象に由来する。
declare 文の strict_types に指定できるのは、0 か 1 の数値リテラルだが、 0x0 や 0b1 のような値も受け付ける。 今回は、PHP 8.1 から追加された、0O または 0o から始まる八進数リテラルを使った。
ソースコードのライセンスを示したこの部分だが、
@@ -273,8 +273,8 @@ $🐘([ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。
@@ -294,15 +294,15 @@ $🐘([if 文なしで条件分岐if 文なしで条件分岐
三項演算子ないし match 式を使うことで、if を一切書かずに条件分岐ができる。 また、&& / || も使えることがある。 遅延評価が不要なケースでは、[$t, $f][$cond] のような形で分岐することもできる。
while、for 文なしでループwhile、for 文なしでループ
不動点コンビネータを使って無名再帰する (詳しい説明は省略する。これらの単語で検索してほしい)。 ここでは、一般に Z コンビネータとして知られるものを使った ($z)。
ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。
@@ -367,8 +367,8 @@ $🐘([ ここでは、私の想定解を解説する。 -まずはソースコードを読んでいく。
@@ -406,8 +406,8 @@ $🐘([次に、ソースコードに書いてあるヒントを読んでいく。
@@ -435,8 +435,8 @@ $🐘([
ここまでわかれば、あと一歩で解ける。すなわち、0x14B499C が # に変換されるような N を見つければよい。
ソースコードはこちら。
@@ -541,10 +541,10 @@ Q; 実際にはもう少しパイプで繋げなければならない。 -コメントにもあるとおり、これは quine (風) のプログラムになっている。 Quine とは、自分のソースコードをそっくりそのまま出力するようなプログラムのことである。
@@ -554,22 +554,22 @@ Q;
$xs がトークンに対応している。変換のロジックは riddle.php とほぼ同じなので省略する。
トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。 このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、LINE から情報を取得している。
Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。 これがあまり美しくないので、toquine.php では、ROT 13 変換を使って難読化した。
以前、https://github.com/nsfisis/big-clock-mode[big-clock-mode] という似たようなプログラムを書いた。 これは tmux の :clock-mode コマンドに着想を得たもので、:clock-mode よりも大きく現在時刻を表示する。
全体の流れは次のようになっている。
@@ -123,8 +123,8 @@フリーの 8x8 ビットマップフォントである、https://littlelimit.net/misaki.htm[美咲フォント 2021-05-05a 版] を使わせていただいた。
diff --git a/public/posts/2022-05-01/phperkaigi-2022/index.html b/public/posts/2022-05-01/phperkaigi-2022/index.html index f4c89fa..df97547 100644 --- a/public/posts/2022-05-01/phperkaigi-2022/index.html +++ b/public/posts/2022-05-01/phperkaigi-2022/index.html @@ -70,10 +70,10 @@多くの素晴らしいトークの中から、特におすすめのものを 5つ選んだ。是非聞いてほしい。引用部分は、リンク先プロポーザルから引用している。
@@ -175,15 +175,15 @@今回は、PHPer チャレンジ用に弊社のトークン問題を 3題作成した。こちらについては別途記事にしているので、そちらを参照されたい。
1位になった。
@@ -191,8 +191,8 @@
去年の参加レポ では、こんなことを書いた。
@@ -221,8 +221,8 @@PHPerKaigi 2023 があるかどうか存じ上げないが、あるとすれば、次の 4つを目標としたい。
diff --git a/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html b/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html index 0fb3911..6aa732d 100644 --- a/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html +++ b/public/posts/2022-08-27/php-conference-okinawa-code-golf/index.html @@ -76,8 +76,8 @@細かいレギュレーションは不明だったので、勝手に定めた。
@@ -133,24 +133,24 @@ ]
割と多くの言語のゴルフで使えるテクニック。e を用いた指数表記で、大きな数を短く表す。このコードでは 10000、5000、2000、1000 を指数表記している。
foreach、for、if などの後ろには、通常 { を続けて複数の文を連ねるが、中身の文を1つにしてしまえば、{ と } を省略できる。C言語などでも使える。
PHP では、$r[] = …​ のような配列の末尾に追加する式を実行したとき、$r が未定義だった場合は $r を勝手に定義して空の配列で初期化してくれる。これを利用すると、$r = []; のような初期化が不要になる。
PHP では、<?php ?> で囲われた部分の外側にある文字列は、そのまま出力される。今回のケースでは、先頭と末尾に必ず [ と ] を出力するので、そのまま書いてやればよい。
組織としての寄付理由は前掲した記事に譲るとして、ここでは、私が社内でこの件を推進した理由について書くことにします。
diff --git a/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html b/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html index 23028a3..c0ae51e 100644 --- a/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html +++ b/public/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line/index.html @@ -56,15 +56,15 @@この記事は、普通の fizzbuzz を徐々に変形して最終形にしていく、という構成で書かれている。最終形を見てどのような仕組みで動いているのか解読してから解説を読みたい、というかたがいれば、 このページ にソースコードがあるので、そちらを先に見てほしい。
PHP で、次のような制約の下に fizzbuzz を書いた。
@@ -110,8 +110,8 @@1行あたりの文字数など、適当に改行を挟めばいいだけではないのか?
@@ -232,7 +232,7 @@ c\@@ -259,10 +259,10 @@ a'
- - 標準的なインストール構成の PHP で実現できること (デフォルトで有効になっていない拡張等を使わないこと) + 標準的なインストール構成の PHP で実現できること (デフォルトで有効になっていない拡張等を使わないこと)
まずは普通に書くとしよう。
@@ -278,8 +278,8 @@ a'for の排除for の排除
for は、3文字もある長いキーワードである。こんなものは使えない。array_ 系の関数を使って、適当に置き換えるとしよう。
@@ -298,8 +298,8 @@ a'
range、array_walk、printf は長すぎるのでどうにかせねばならない。ここで、PHP の可変関数を使う。可変関数とは、関数名が文字列として入った変数を経由して、関数を呼び出す機能である。
@@ -322,8 +322,8 @@ a'
今回使ったテクニックを説明する前に、余談として、文字列リテラルの短縮法として今回採用しなかったものを紹介する。
@@ -366,8 +366,8 @@ F.実際に使った手法の説明に移る。
@@ -382,7 +382,7 @@ F. // $a ^ $b は次のコードと同じ $result = ''; for ($i = 0; $i < min(strlen($a), strlen($b)); $i++) { - $result .= $a[$i] ^ $b[$i]; +$result .= $a[$i] ^ $b[$i]; } echo $result; @@ -447,8 +447,8 @@ o'完成したものがこちら。
@@ -604,8 +604,8 @@ _! );PHP は、スクリプト言語の中だとシンタックスシュガーが少ない (体感)。この挑戦は不可能に思われたが、PHP マニュアルとにらめっこしていたらなんとかなった。
@@ -615,8 +615,8 @@ _!
PHP では、バッククォートを使ってシェルを呼び出せる。これは shell_exec 関数と等価である。さて、PHP ではバックスラッシュによる行継続が使えないと書いたが、シェルでは使える (当然だが、呼び出されるシェルに依存する。Bash なら大丈夫だろう。知らんけど)。