これは はてなエンジニアアドベントカレンダー2023 2日目の記事です。
トップバッターは緊張するけど、順番が回ってくるまで長い間ソワソワするのも嫌、という理由で例年2日目を狙うようにしている id:pokutuna です。今年も成功しました。
観光名所とは
目を閉じれば思い出す、あのコード... あの Issue...
あなたが Web 系のエンジニアであれ、趣味で開発している方であれ、必要に応じてライブラリやフレームワークのコードを読むのはよくあることでしょう。公開の場で開発されているソフトウェアは、ソースコードだけでなく、開発コミュニティでの議論やバグ報告なども見ることができます。
リポジトリを覗き見していると、思いもよらない実装や、記憶に残るディスカッション、バグレポートまでいろいろな営みが見つかります。
私はそういったものを「観光名所」と呼んでコレクションしています。
今日はよく知られているソフトウェアの GitHub 上にある観光名所をピックアップして紹介します。
観光名所たち
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED (facebook/react)
facebook/react@60ad369 - packages/react/src/React.js#L128
export { ... ReactSharedInternals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
これはちょっと有名かも、ReactSharedInternals
が export される際の物騒な名前。React の内部状態が入っています。
まあ必要があって export しているわけで、テストや react-dom など他の packages/
以下からちょいちょい参照されている。package として公開しているが、これに依存した機能なんて作るなよというメッセージが明確に表現されています。まあドキュメントやコメントで言っても読まれませんからね。
Node.js の HTTP ヘッダの小文字化 (nodejs/node)
nodejs/node@60ffa9f - lib/_http_incoming.js#L279
function matchKnownFields(field, lowercased) { switch (field.length) { case 3: if (field === 'Age' || field === 'age') return 'age'; break; case 4: if (field === 'Host' || field === 'host') return 'host'; if (field === 'From' || field === 'from') return 'from'; if (field === 'ETag' || field === 'etag') return 'etag'; if (field === 'Date' || field === 'date') return '\u0000date'; if (field === 'Vary' || field === 'vary') return '\u0000vary'; break; case 6: if (field === 'Server' || field === 'server') return 'server'; if (field === 'Cookie' || field === 'cookie') return '\u0002cookie'; if (field === 'Origin' || field === 'origin') return '\u0000origin'; if (field === 'Expect' || field === 'expect') return '\u0000expect'; if (field === 'Accept' || field === 'accept') return '\u0000accept'; break; case 7: if (field === 'Referer' || field === 'referer') return 'referer'; if (field === 'Expires' || field === 'expires') return 'expires'; ...
Node で HTTP ヘッダを扱う際、ヘッダ名を小文字で扱っていることに気づきます。RFC2616 → RFC7230 → RFC9112 の歴史ある仕様にあるように、ヘッダ名は大文字小文字を区別しないので、すべて小文字に寄せているようですね。
何度も実行されるところなので、パフォーマンス優先のためになかなか激しい実装になっています。toLowerCase
を呼ぶ回数を減らすため、一般的なヘッダはハードコードされており、文字列比較の回数を減らすため前段で文字列長で分岐しています。
返す文字列の1文字目がフラグになっている、というのもなかなかです。同じヘッダが複数回出現する場合の区切り文字や、Cookie & Set-Cookie の扱いを制御しています。
VSCode のコマンドがローカライズされる (microsoft/vscode)
Don't localize command names on the command palette · Issue #4679 · microsoft/vscode
VSCode の開発版である Insiders Build にリリースされた変更。
コマンド名が翻訳されて、git pull
ではなく git プル
と入力する必要がでてくる。やめてくれという意見で CJK 圏の気持ちが一つになった事件。
Issue を立てるだけでなく、繰り返し問題を説明する @espresso3389
さんの活躍が光る Issue です。これが安定版に降ってこなくて本当に良かったですね。ソフトウェアをローカライズする際の難しさも垣間見えます。
A picture of a cute animal (moby/moby ほか)
moby/moby@75546e1 - .github/PULL_REQUEST_TEMPLATE.md
Please provide the following information: ... **- A picture of a cute animal (not mandatory but encouraged)**
moby は、以前モノリシックな構造だった Docker リポジトリをコンポーネント化していったもので以前は docker/docker でした。今も Docker の実装に使われています。その moby の Pull Request テンプレートには、かわいい動物の画像を貼るコーナーがあります。
例
- https://github.com/docker/compose/pull/11213 (moby じゃなかった)
- https://github.com/moby/moby/pull/32061 (アスキーアート)
- https://github.com/moby/moby/pull/27455 (どういう状況?)
- https://github.com/moby/moby/pull/34895 (🐼で済ませる)
でも最近の Pull Requests を見るに、そんなに貼られてはいなさそう。
その他 docker 関連リポジトリにおいても動物画像コーナーがしばしば見られます。
- docker/compose@c582470 - .github/PULL_REQUEST_TEMPLATE.md
- docker/cli@c1455b6 - .github/PULL_REQUEST_TEMPLATE.md
Steve Wozniak is not boring (moby/moby)
moby/moby@75546e1 - pkg/namesgenerator/names-generator.go#L852
if name == "boring_wozniak" /* Steve Wozniak is not boring */ { goto begin }
こちらも moby から、Docker コンテナの自動命名にある唯一の例外。
docker run
でコンテナを起動した際、ランダムな名前が割り当てられるのはこの names-generator.go
の実装によるものです。"形容詞" と "科学者やハッカーの名前" の2つのテーブルから選んで結合したものになる。
形容詞のテーブルに boring
、人名のテーブルに wozniak
が含まれていますが、boring_wozniak
という名前がコンテナに割り当てられることだけはありません。なぜなら Apple 創業者の Steve Wozniak は退屈ではないので。
goto
で戻ってやり直しているのも普段あまり見ないので面白いですね。
そういえば Elasticsearch の node 名は Marvel キャラクターから選ばれるんだっけ、と見に行ったら 5.0 からなくなっていた。めっちゃ前じゃん elastic/elasticsearch@v2.4.6 - core/src/main/resources/config/names.txt
Trick and AttributeError 事件 (pypa/pipenv)
Halloween easter egg breaks · Issue #786 · pypa/pipenv
pipenv は Python のインタプリタと依存ライブラリのバージョンを管理する bundler ツール。
普段のプログレスバーは 🐍 の絵文字で表示されるところ、ハロウィンだけ 🎃 になるというイースターエッグが仕込まれていました。しかしそこにバグがあり、ハロウィンだけ例外が出て依存をインストールできなくなる事態に。
ちょうどこれでデプロイ不能になってハマったのでよく覚えている。ここがいきなり壊れると思わないだろ。
累計100万DLを突破したダイエットアプリ(無料)の『もぐたん』! (google/zetasql)
google/zetasql@589026c - zetasql/compliance/testdata/strings.test#L911
-- ARRAY<STRUCT< STRING, formatted_description STRING >> [ { "累計100万DLを突破したダイエットアプリ(無料)の『もぐたん』!\nおかげさまで、ヘルスケア/フィットネス 無料カテゴリで1位獲得!\n\n◆かんたんスタンプ入力 \n文字で書かなくても食べ物スタンプで簡単に記録出来ちゃう!\n\n◆『もぐたん』がみんなを応援\n入力する度にもぐたんがゆるくて可愛いコメントをくれるよ!\n毎日体重を入力して『もぐたん』の「きせかえ」をGETしよう!\n\n◆ダイエットの成果はグラフでチェック\n体重を入力するとグラフに反映されるから変化がまるわかり!\n摂取カロリーの推移もグラフでチェック出来ちゃう!\n\n◆体重と一緒に運動スタンプを入力\n運動もスタンプでかんたん入力!\n毎日どのくらいダイエットしたかがひと目でわかるよ!\n\n◆ 自動カロリー計算機能\nプロフィールを入力すると、あなたに合った摂取カロリーの目安がわかるよ!\n\nhttps://itunes.apple.com/jp/app/daietto-ji-lumogutan-ke-aiisutanpude/id882365789", '"累計100万DLを突破したダイエットアプリ(無料)の『もぐたん』!\\nおかげさまで、ヘルスケア/フィットネス 無料カテゴリで1位獲得!\\n\\n◆かんたんスタンプ入力 \\n文字で書かなくても食べ物スタンプで簡単に記録出来ちゃう!\\n\\n◆『もぐたん』がみんなを応援\\n入力する度にもぐたんがゆるくて可愛いコメントをくれるよ!\\n毎日体重を入力して『もぐたん』の「きせかえ」をGETしよう!\\n\\n◆ダイエットの成果はグラフでチェック\\n体重を入力するとグラフに反映されるから変化がまるわかり!\\n摂取カロリーの推移もグラフでチェック出来ちゃう!\\n\\n◆体重と一緒に運動スタンプを入力\\n運動もスタンプでかんたん入力!\\n毎日どのくらいダイエットしたかがひと目でわかるよ!\\n\\n◆ 自動カロリー計算機能\\nプロフィールを入力すると、あなたに合った摂取カロリーの目安がわかるよ!\\n\\nhttps://itunes.apple.com/jp/app/daietto-ji-lumogutan-ke-aiisutanpude/id882365789"' } ]
zetasql は BigQuery や Cloud Spanner 内で利用されている Google の SQL Parser & Analyzer です。
その utf8 文字列のテストデータとして「もぐたん」という iOSアプリの App Store 説明文らしきものが使われています。そこは Play Store じゃないんかい。
zetasql は、BigQuery 大好きパーソンが中を知りたい時に当たれる数少ない公開コンポーネントです。謎に満ちており、OSS ではあるもののコミュニティ主導ではなく ZetaSQL Team
ユーザが数週間に1回変更をまとめて push する、人の侵入を望まない霊峰のような風情。
もぐたんは現在サービス終了していますが、かわいいクマチャンが出てくるアプリです。zetasql との温度差で交互浴の気分になります。
参考
- Google の SQL parser/analyzer の ZetaSQL とは何であるか | by apstndb | google-cloud-jp | Medium
- 公開論文から学ぶ Google のテクノロジー : パート 3:データベース技術編 | Google Cloud 公式ブログ
Promise.race で DNS & IP 両方にリクエストを投げる (googleapis/gcp-metadata)
googleapis/gcp-metadata@27f0a12 - src/index.ts#L186-L187
let responded = false; const r1: Promise<GaxiosResponse> = request<T>(options) .then(res => { // ... }) const r2: Promise<GaxiosResponse> = request<T>(secondaryOptions) .then(res => { // ... }); return Promise.race([r1, r2]);
これは Google Cloud のメタデータサーバーにリクエストする実装です。
メタデータサーバーは GCP 内のネットワーク内から到達でき、実行環境に応じた情報取得や認証を行うため、ほとんどのクライアントライブラリが内部的に叩いています。
ここではメタデータサーバーの metadata.google.internal.
と、それを解決したリンクローカルアドレスの 169.254.169.254
に並行にリクエストを投げて先に成功した方を使うという実装になっています。
そんなことしていいの、と驚くけど、GCP 内の名前解決が遅い環境では 169.254.169.254
が先に結果を返すでしょうし、GCP 外のユーザのローカル環境などでタイムアウト待ちになったとしても metadata.google.internal.
が解決できないので名前解決程度の短時間で失敗できる、という感じでしょうか。合理的ではあります。こんなコアっぽいところでリクエストを倍にしちゃうんだ。
関連: GCP の Application Default Credentials を使った認証 - ぽ靴な缶
命名に関する議論
命名に関する議論は紛糾しがちです。
GitHub は 2020 年 10 月にデフォルトブランチ名を master
から main
に変更しました。日本語圏だけでもいろいろな意見が飛び交いましたね。
The default branch for newly-created repositories is now main - The GitHub Blog
先程の Docker コンテナ命名の実装についても、議論の末に変更を凍結する判断がされています。
Freeze the namesgenerator package against new additions by tianon · Pull Request #43210 · moby/moby
私たちはこの変更についてメンテナ会議で議論し、私たち全員がこのパッケージの最初の アイデアを気に入っていたにもかかわらず、何年もかけてこのパッケージは 望ましい以上のメンテナンスが必要になり始めたという結論に達しました。
いくつかの例を挙げますと、何年もの間、名前の組み合わせが不幸な組み合わせになったり、形容詞がすべての状況に適していなかったり、否定的な意味を持つようになったり、リストの人々が物議を醸すようになったりしたため、私たちはリストの変更を余儀なくされてきました。さらに、技術的な制限(姓が一意でないこと、名前の長さ、名前がアスキーに限定されているため、暗黙のうちに多くの地域の名前が除外されていること)もあり、事態を複雑にしています。
リンクされているコミットでは、形容詞の cocky は人に付けるのは適切でなかったり、kickass, insane など俗語的にはポジティブな意味(ヤバすぎ、のような)でも、フォーマルな文脈では厳しいので消したり置き換えられたりしています。
この "物議" が指すのは、エプスタイン事件において疑惑のある Marvin Minsky や、それへの言及が問題となった Richard Matthew Stallman についての話で、人名テーブルから除く変更が行われています。
リチャード・ストールマン氏、MITの役職とFSF総裁を辞任 エプスタイン関連コメントへの批判で - ITmedia NEWS
かつてはおもしろ機能だったものが、社会的な価値観の変化やより広い人々を包摂するにつれて、不適切とみなされるようになっていく、ということが起きています。
他に命名に関する議論で思い出されるのは、FactoryGirl や Tsunami でしょうか。観光名所というと面白がっているニュアンスで聞こえるかもしれませんが、fun ではなく controversial な、記憶に残るものとして紹介します。
FactoryGirl が FactoryBot に変更 (thoughtbot/factory_bot)
Repository Name · Issue #921 · thoughtbot/factory_bot
こちらは Ruby のテストデータのファクトリライブラリである FactoryGirl が、FactoryBot にリネームした際の議論。
FactoryGirl は、Factory パターンと Rolling Stones の曲に由来する名前ですが、「名前の由来はなんなの?」という質問に端を発し、女性差別的ではないか、男性多数なソフトウェア業界のバイアスがあるのではないか、という議論から FactoryBot にリネームされました。
リネーム反対意見に同意する emoji の数や、女性による変えなくて良いというコメントが繰り返し言及される中(「当の女性が問題にしていないじゃないか」的な)、冷静にリネームの判断を下していてすごいですね。6 年前の話ですが、今やると emoji の傾向も大分変わるんじゃないでしょうか。不快だと思っていてもこの荒れた Issue では表明するのも難しいでしょう。
一方 FactoryGirl の Python 版といえる FactoryBoy はそのまま行くという判断をしています。
- factory_girl --> factory_bot by alexgleason · Pull Request #442 · FactoryBoy/factory_boy
- Consider renaming to FactoryPy or the like · Issue #912 · FactoryBoy/factory_boy · GitHub
Tsunami の命名に関する議論 (google/tsunami-security-scanner)
津波のような攻撃から身を守るセキュリティスキャナーという命名ですが、Tsunami って命名はどうなの? 東日本大震災の津波を思い出す人もいるんじゃない? という Issue です。master/slave や whitelist/blacklist は、どこか外の話のように感じる人も多いと思いますが、これは日本人が当事者になったトピック。
当時はてなブックマークでも話題になっていました。
Googleのセキュリティスキャナー「Tsunami」、名称がGitHubで議論呼ぶ 関係者が参加し釈明 - ITmedia NEWS
性別の話に比べ、かなり抑制的に議論が行われていると思います。津波という名前だから破壊する方のツールかと思った、という尤もな指摘もあります。
...それはそれとして、この議論の数ヶ月後に、google/tsunami が push されています。TSUNAMI (TypeScript Untar Multiple Reads) の略だそうです。偶然でしょうが、変なオチがついた気持ちになりました。
XML は暴力ではない (sparklemotion/nokogiri)
Removing reference to violence. · sparklemotion/nokogiri@ddd8e1d
- XML is like violence - if it doesn’t solve your problems, you are not - using enough of it. -
ポリティカルコレクトネス的な変更で思い出すのは Nokogiri です。Ruby の XML パーサーですが、README から以下の行が暴力を賛美しているということで削除されました。
XML is like violence - if it doesn’t solve your problems, you are not using enough of it.
(訳: XML は暴力のようなもので、それで問題が解決しないのであれば、使い方が足りないのだ。)
まあ明らかにジョークだし、このぐらいいいんじゃないの...と思うものの、暴力に怯える状況で XML をパースする際には複雑な気持ちになるかもしれません。
自分がどの立場になるか、という問題は常にあります。
例えば Facebook にクビになった人は、React の __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
を面白がれるでしょうか。いやしかし、他者の痛みを想像しつつも、勝手な想像で他人の喧嘩をしないほうがいい、というのが私の気持ちです。
もはや GitHub デフォルトブランチが main
なのが当たり前になり、むしろ master
を見ると古臭く感じるようになりました。そんな心情の変化に時代の流れを感じますね、とここまでを締めることにする。
その他小粒なもの
特に説明しても面白さに資さないけど、記憶に残るもの
- 猫がキーボードの上を歩いた結果立った Redis の Issue
if enabled then "Disabled"
- Google Analytics の
dimesion1
~dimension200
までの型定義、metrics1
~metrics200
もある
OSS 以外
タイトルの引き欲しさに OSS と書いたので、ここまでオープンソースライセンスと言えるものを挙げてきました。それ以外で記憶に残っているものをちょっと紹介します。
"You are not expected to understand this" (Version 6 Unix)
超有名な一節。コードが分かる人に比して圧倒的にコメントが流行っている。僕もわかりません。
今は BSD で配布されているようですが原典的にはこの枠で。
2230 /* 2231 * If the new process paused because it was 2232 * swapped out, set the stack level to the last call 3333 * to savu(u_ssav). This means that the return 2235 * actually returns from the last routine which did 2236 * the savu. 2237 * 2238 * You are not expected to understand this. 2239 */ 2240 if(rp->p_flag&SSWAP) { 2241 rp->p_flag =& ~SSWAP; 2242 aretu(u.u_ssav); 2243 }
解説の翻訳 あなたが見た中で最も有用なコードコメントは何ですか? - Quora
SQLITE_TEMP_FILE_PREFIX "etilqs_" (mackyle/sqlite)
mackyle/sqlite@18cf471 - src/os.h#L65-L79
#ifndef SQLITE_TEMP_FILE_PREFIX # define SQLITE_TEMP_FILE_PREFIX "etilqs_" #endif
SQLite は軽量でファイルベースのデータベースです。著作権を放棄した Public Domain で公開されています。 身近なモバイルアプリやブラウザのローカルなデータベースとして組み込まれていたりします。Chromium の履歴やブックマークでも使われているようですね。SQLite abstraction layer
そんな SQLite の一時ファイルは、sqlite を逆さに読んだ etilqs_
が prefix になっています。
理由はこちらの @EzoeRyo 氏のツイートでどうぞ。
マカーフィーがSQLiteを使っていて、C:\tempに一時ファイルを作ったため、ファイルを見て疑問に思った馬鹿なユーザーがsqliteを検索し、出てきた開発者の電話番号に「テメェ責任者かコラ、ファイル消しやがれゴルァ」という迷惑電話をかけまくったため、逆さ読みのetilqs_に変更された。
— 江添亮 (@EzoeRyou) 2023年6月13日
おわりに
コレクションしていた観光名所を一通り放出しました。
みなさんの知る観光名所はどんなものがあるでしょうか? コメントやはてなブックマークコメントでぜひ教えてください!! チャンネル購読と、高評スターもお願いします。
また、労働をしていると社内の開発リポジトリに観光名所を見つけることもあります。きっと皆様の会社にもあることでしょう。
- 様々なしがらみで修正できずそのままになっている typo
- 議論が白熱しすぎてもはや喧嘩している Issue
- デカい障害を引き起こした名コミット
- 狂った命名
- 遺言に見えるコメント
- Revert を Revert した回数最高記録
- いちばん長い SHA1 のゾロ目を探して遊ぶ
などなど、興味がある方はこちらから入社してください。日本全国フルリモートOK!!
実用的な情報
ちなみに GitHub のソースコード表示中に y を押すと、URL が main
などブランチ名から コミットID が含まれるものに変わります。こういう記事や、ドキュメントを書くときに便利ですね。ファイルへのパーマリンクを取得する - GitHub Docs
また、cocopy でリンクテキストを生成するとさらに便利ですよ。
blog.pokutuna.com
こんな関数で、デフォルトは Markdown、Shift キーを押している時は Scrapbox 記法でコピーしています。
({title, url, modifier}) => { const pattern = /https?:\/\/(.+)\/(?<user>.+)\/(?<repo>.+)\/blob\/(?<rev>[^/]+)\/(?<file>[^#]+)(?<hash>#.+)?/; const g = pattern.exec(url).groups; title = `${g.user}/${g.repo}@${g.rev.substr(0,7)} - ${g.file}${g.hash || ''}` return modifier.shift ? `[${title} ${url}]` : `[${title}](${url})`; }
この記事は はてなエンジニア Advent Calendar 2023 2日目の記事でした。
明日の担当は id:mechairoi さんです。楽しみですね。
追記
ブックマークありがとうございます。
挙げてもらった観光名所にリンクしておきます。
ちょっと小粒よりだけど Sidekiq にある❤という名前のメソッドはおもしろ命名なので観光名所としてオススメですhttps://t.co/FkHiOH6amS
— 藤秋 (@f_subal) 2023年12月2日
OSS 観光名所を貼るスレ - ぽ靴な缶 https://t.co/Js9w9VQlZI
「デカい障害を引き起こした名コミット」の例だとaxiosでXSSを防ぐために"on〇〇"を含むクエリパラメータを全部エラーにしたやつが思い出されるかなhttps://t.co/z20FtZkLzx
— 藤秋 (@f_subal) 2023年12月2日
TypeScript が急に 3.3.3333 ってバージョンを作って怒られる回 https://t.co/nnqwJrUGBG とか、Jest が10000個目の PR で馬鹿になっちゃった回 https://t.co/KTNhPWDLQx とか好き
— ksakahieki@恋垢 (@ksakahieki) 2023年12月2日
OSS 観光名所を貼るスレ - ぽ靴な缶 https://t.co/ScIsJyGC0e
GitHub のRails リポジトリがハックされたやつも載せてほしい https://t.co/4KqXswesMX / “OSS 観光名所を貼るスレ - ぽ靴な缶” https://t.co/vbd1Nx698o
— suginoy (@suginoy) 2023年12月2日
OSS 観光名所を貼るスレ - ぽ靴な缶これも <a href="https://tech.a-listers.jp/2011/06/17/epic-fail-on-github/" target="_blank" rel="noopener nofollow">https://tech.a-listers.jp/2011/06/17/epic-fail-on-github/</a>
2023/12/03 00:33
OSS 観光名所を貼るスレ - ぽ靴な缶個人的にはこれ→<a href="https://github.com/cocoa-mhlw/cocoa/issues/95" target="_blank" rel="noopener nofollow">https://github.com/cocoa-mhlw/cocoa/issues/95</a>「OSのプロキシ設定を無視したHTTP接続を行っている」
2023/12/03 01:34
おもしろかった。個人的にはUI LibraryのAnt Designで、クリスマスになると勝手にデザインが変わる時限爆弾を思い出した。https://t.co/QC92u9sa0L / “OSS 観光名所を貼るスレ - ぽ靴な缶” https://t.co/a3kEb8CzE3
— snagasawa (@snagasawa_) 2023年12月2日
弊社のリポジトリでは変数の横に*が10個付いたCのコード(ポインタのポインタの…って10回分)が発見されて話題になったことがあるhttps://t.co/PMdgMEqy3c
— ぞりお (@__zorio__) 2023年12月3日
これは楽しいw/命名関係は色々意見があるよねぇ…/個人的には古いけど「membarrier()システムコール」の話が大好きw https://t.co/yBJF2NuIkL / 他39件のコメント https://t.co/1EtRLNGIF8 “OSS 観光名所を貼るスレ - ぽ靴な缶” (331 users) https://t.co/FJZlUX0fAO
— wisboot (@wisboot) 2023年12月3日