TOMLというミニマル言語
設定ファイルをjsonからTOMLに移行
ツールなんかを作るときある程度は自由度持たせるために設定をjsonで書いていたが、最近どうしてもカッコが面倒になってきた。
パラメータが少ない時なんかは問題無いんだけど、データが増えてくるとどうしても書くのが手間。(コメントも書けないし)
そんなことを思っていたらTOMLという物を発見。
# コメント Key1 = "Value1" Array = [1, 2, 3] [Object] Key3 = "Value2" [ObjectInArray] Array = ["a","b","c"]
キーバリューペアの形式で書いていく形になる。
jsonの様にArrayやObject型などがあるため移行もしやすそう。
コメント
ハッシュ記号(#)から改行までがコメントとなる。
# コメントだよ Key = Value #こんなのも可能
文字列
文字列の記述は4種類の方法がある。
基本
ダブルクォートで囲むと文字列として扱われる。
クォート、バックスラッシュなどはエスケープをする必要がある。
エスケープシーケンスの短縮形も用意されている。
\b - backspace (U+0008) \t - tab (U+0009) \n - linefeed (U+000A) \f - form feed (U+000C) \r - carriage return (U+000D) \" - quote (U+0022) \/ - slash (U+002F) \\ - backslash (U+005C) \uXXXX - unicode (U+XXXX) \UXXXXXXXX - unicode (U+XXXXXXXX)
複数行文字列
改行も文字列として扱いたい場合、ダブルクォート3つで囲むことで表現出来る。
文字列の頭にすぐ改行を入れた場合その改行は無視される。
string = """ TOML Test TOML Test"""
リテラル文字
正規表現のパターンを書くような場合、エスケープをするケースが増えとても面倒なケースが多い。
TOMLはリテラル文字列をサポートしているので、利用することでエスケープを省略して利用することが可能となっている。
リテラル文字を利用する場合シングルクォート囲むことで利用できる。
regex = \`[\d]+\'
複数行リテラル文字
リテラル文字ではエスケープを利用することができないため、シングルクォートを利用することができない。
TOMLではリテラル文字の複数行をサポートしているのでそちらを利用する。
シングルクォートを3つで囲むことでリテラル文字として扱われる。
整数
全ての数は整数として扱われる。
正の数は頭にプラスを付けても、つけなくても表現できる。
負の数は頭にマイナスを付けて表現する。
大きな数字を表現する場合、アンダースコアを数字の間に挟むことで区切り表現をすることができる。
1_000 123_456_789
整数の表記を0から始めることはできず、2進数8進数16進数の形式で表現することは出来ない。
精度は64bit(long)
小数
小数部と指数部で表現が可能。
マイナス、プラスやアンダースコアでの区切りは整数と同じルールで利用可能
123.456_790
精度は64bit(double)
ブーリアン
ブーリアンはただのトークン。
小文字のみ利用可能。
日付
日付型はRFC 3339に準じる。(この規格しらないけど)
年-月-日T時:分:秒-UTCオフセットの形式になる。
UTCオフセットを0にする場合"年-月-日T時:分:秒Z"と記述すればよい。
日本のUTCオフセットは09:00なので 2016-02-29T00:00:00-09:00 となる。
タイムゾーンを利用するような場合以外は使わないとは思うが。
ちなみに秒には小数表現が可能。
配列
配列は[]この括弧で囲まれたプリミティブ型の集まり。
空白は無視され、要素はカンマで句切られる。
データ型は共通である必要がある。
array = [1, 2, 3] matrix = [[1, 2, 3],[4, 5, 6]] arrayStr = ["aa", "bb", "cc"]
テーブル
キーとバリューのペアからなる集まり。(jsonのオブジェクト型と同じ扱いができる)
テーブルはで囲まれたテーブル名から始まる。
配列表現と同じ括弧を利用するが、区別はしやすい。
配列の場合必ず値として表現するが、テーブルは値である必要はなく [table name] この様に記載する。
テーブルはで開始され、次のテーブルの開始またはファイルの終端までこのテーブルに属する。
使える文字は英数字、アンダースコア、ダッシュのみ(a-zA-Z0-9_-)
[table] key1 = "value1" key2 = "value2" [table2] key1 = "value1" key2 = "value2"
と書いた場合jsonでは以下の構造を表現する。
{ "table": { "key1": "value1", "key2": "value2" }, "table2": { "key1": "value1", "key2": "value2" } }
ネストしたテーブルを表現する場合ドットを利用する。
[table] key1 = "value1" key2 = "value2" [table.NestTable] key1 = "value1" key2 = "value2"
この場合jsonで以下の構造を表現する。
{ "table": { "key1": "value1", "key2": "value2", "NestTable": { "key1": "value1", "key2": "value2" } } }
上位のテーブルを記載する必要が無い(値が存在しない)なら省略することも可能。
上位のテーブルを省略しても、後の行で上位のテーブルの内容を書くことはできる。
ただ、キーやテーブルの再定義は出来ないため、各定義は必ず1つである必要がある。
[table] kay1 = "value1" [table] # これはNG kay2 = "value2"
テーブル配列
テーブルの再定義は行えないが、テーブルの配列を定義することはできる。
テーブル名を [ [table name] ] 括弧2重で囲むことで同じ名前のテーブルは配列の要素となる。
テーブルは表記順番で挿入され、キーとバリューのペアを持たないテーブルはからのテーブルとして扱われる。
[[TableArray]] Key1 = "Value1" [[TableArray]] Key2 = "Value2"
これは以下のjsonの構造となる。
{ "TableArray":[ { "Key1" : "Value1" }, { "Key2" : "Value2" } ] }
ネストしたテーブルの配列も定義することができる。
その場合子テーブルにも括弧2重で囲めばよい。
まとめ
自分が使いそうな表記はこのぐらい。
頭でも書いたがjsonから機能の置き換えとしては十分。(むしろこっちのが良く思える)
パーサーも自分が使う言語はほぼあるので困ることはなさそう。
ただ、javascriptを使う時だけはなんとも言えない。
jsonはそのままjavascriptで使うことが出来るのに対して、TOMLは一度パーサーを通さないといけないから悩みどころ。
でも、製品で使う様な機能でない限りTOML採用かな。
参考URL
https://github.com/toml-lang/toml
※まだバージョンは0.4.0と1.0になってない所だけ注意