jsonにコメントを書きたいがためだけの…つぅーまっちな何かしら

この記事を読んで、きゃーすてきーと思ってはいけない。

jsonにまつわるやや不愉快な点については、これまで二つばかり叫んでみたりもした。LooseJSONDecoderの件と、ConfigParserの件ね。ほかにもminifyな話も言ったことがある。

それらを叫んでいた際に気付いてなかったわけではないんだけれど、わりかし敷居の低い「えれえがんと」なやり方ってのはあるにはあり、そして「あえて言わないようにしてた」。ま、言わなかった理由は後述として、たとえばこういうことさね:

1 import io
2 import json
3 from mako.template import Template # require mako.
4 #                                    if you dont have it,
5 #                                    do "pip install mako".
6 
7 jsontext_what_we_want = Template(
8     io.open("mydef.jsont", encoding="utf-8").read()).render()
9 obj_what_we_want = json.loads(jsontext_what_we_want)

なんだステキじゃないかぁ、と:

mydef.jsont | jsonのようでそうでもないjson
 1 {
 2     "inputs": [
 3         {
 4             "orig": "hoge.mkv",
 5             "trim": ["00:31:51.410", "00:35:14.200"],
 6             "target_time": [
 7                 ["00:32:13.000", "00:32:13.700", [1, "", "volume=0.0025"]]
 8 <%doc>一時的にコメントアウトしとくねーっ
 9                 , ["00:32:33.530", "00:32:34.265", 0]
10 </%doc>
11             ]
12         }
13     ]
14 }

何が「アカン」のか、一つはすぐにわかるかいね。わかって欲しいかなぁ。「html内にjavascriptを埋め込む」際のソースを読み書きする苦痛にお馴染みなら、わかるよね? 上で pygments がしっかり騙されちゃってるのと同じく、「syntax highligting やその他コードアシスト」の恩恵を受けにくくなるのよ、こういう「ちゃんぽん」てさ。

つまり、「デメリット」は以下の通り:

  1. Python は Ruby と違って、こういう高機能テンプレートエンジンは「組み込み」ではなく、(ここで例にした Mako などの)サードパーティー製のライブラリを別途インストールする必要がある。
  2. 開発環境(特にエディタ)の機能の恩恵を犠牲にしがちである。
  3. テンプレートエンジンの特殊文字などのエスケープとの格闘のはじまりはじまり。

json と mako の相性はそれほど悪くないとは思う。ただ、たとえば ${var} などに逐一反応してしまうので、これは特にシェルスクリプトととの組み合わせはなかなかに最悪だったりする。json だと文字列の中に埋め込まない限りは mako のスペシャルな仕様と衝突はしない。

というわけで、はっきりいって「json にコメントを入れたい」だけのために背負いこむデメリットなのかどうか、てのが微妙で、まぁそういうわけであえて言ってこなかったというわけ。ただこういうの、言わないと気付かない人も結構多いと思うわけで。なので、今日今ワタシが欲しくなったタイミングなので、あえて今更紹介しとこうかなと思った次第。


2022-03-08追記とか蛇足とか:
まずは蛇足から。どこかで書いたつもりになってて書いてなかった。まさに今日必要で、まさにそうしたんだけれど、「json にはコメントは書けない」に対して「諦める」というのも一つの手:

あくまでも json 仕様の枠内で
1 {
2     "A1": 1,
3     "A2": 2,
4     "_COMA1_": "幸甚指数",
5     "_COMA2_": "カタルシス度"
6 }

この例の場合、「キー名は短くしたいので「A1」がわかりにくかろうとわかりやすく長くすることはしないかわりに、意味の説明を別キー「_COMA1_」で行う」てこと。キー名にルールを設けるというだけね。これが「馬鹿げてる」かと言えば、それは考え方次第。json を受け取って処理するプログラムをどう書くか、あるいは人が書いたものならどう書かれてるか、だけの話。なんというか、インターネットに公開される「情報」って、完成品ばかりが好まれる傾向が高いと思うのだけど、ワタシが思うに、日々の日常はむしろそういう「完全」な解法だけで成り立ってはいなくてこういう妥協の積み重ねのはずでしょ、だからこういう「バカな考え方」もちゃんと言うようにした方がいいと思ってるんだよね。

実際こうして「諦め」たからこそ生まれるメリットも出てくるハズでしょ。例にしたものの場合、「特別扱いしないなら _COMA1_ は特別じゃない」んだから、処理したくなったら「何も特別なことをせずとも特別なことを出来る」。これが言語組み込みのコメントだったならそうはいかない。コメントを処理できるかなり高等なインフラと技術が必要。そう、結局は「考え方次第でどうとでもなることもある」てことだよ。

追記の2つ目。

元のネタは Python での例だったけれど、ここ最近 Go 言語ネタで同じようなことを結構やってるんで、興味があったらどぞ:

Go 言語標準添付ライブラリの text/template ネタから始まり、「汎用テンプレートエンジン」としてはそれが不満なのでサードパーティ製の jet で遊び…というのが大きな流れだけれど、「json にコメントを入れたい」ネタとしては text/template の範囲内で実際に上のリンク内でやってる zip2tar.go、tempcleango.go 内に組み込んでる。そう、ワタシはなんだかんだこのアプローチ、「積極的におススメすることはしない」としつつ自分では日常使いはしてるんだよね。