Livedoorブログからの移動

何かしらのアプリケーション(シェルコマンドレベルでも)を書くとき, 設定ファイルが必要になることは多い. rubyだったらYAMLとか, jsだったらJSONとか, いくつかの言語にはデファクトスタンダードがあるけどscalaにはまだ無いように思えるので, scalaで(比較的)簡単に使える設定ファイルの方式の一覧と, その選び方について自分の考え方をまとめてみようと思う.

propertiesファイル (Java)

Javaで用いられていた, 以下のようなファイル.

key = value1
key.child = value2

利点

awk・シェルスクリプトとの相性が良い. そのため, これらと組み合わせる場合には便利である. 例えば, scalaでコマンドラインインターフェイスを作って, その補完ファイルをzshで書いた時に, 双方から設定ファイルを読み込まさなきゃいけない時など.

後, Java組み込みのAPIを使うのでもしかすると高速に読み書きができるかも. 未調査なので本当かは知らない.

欠点

階層的データ構造をつくろうとした時の記述量の増大, 多言語との互換性の低下, 文字列しかデータが扱えない, など欠点はいっぱいある.

XML

利点

scala言語構造にXMLリテラルがある. 実のところそれくらいしか利点はないように思う.

欠点

記述量が多い. 文字列しか扱えない. 正直設定ファイルとしてみるとJSONの下位互換なのではないかと思っている.

JSON

利点

記述量が比較的少なく, また人間が読みやすい. JavaScriptなどでも用いられるので多言語との互換性も高められる.

欠点

組み込みのパーサは使いづらいので, play-jsonなど別途ライブラリを追加しないと使えない.

scalaプログラム

scalaで型(objectなりclassなり)を定義し, それをこのページのようにリフレクション経由でコンパイルすることで設定ファイルとする方法.

利点

静的型付きの設定ファイルが書ける. 設定ファイルの入力ミスについて自分であーだこーだやる必要がない..

また, scalaであるので関数を設定ファイルにかける. 従って, 例えば操作対象のファイルの情報を設定ファイルで記述したいとき, 他の方法だと拡張子のリストとか, 正規表現とかで扱うしかないが, scalaであればFile -> Booleanの関数として書ける.

最後に, scalaの暗黙変換とかを使うことで, 記法もかなり自由に設定できる.

欠点

readが遅く, writeが難しい. ただ, 事前コンパイルができるのであれば多分事前コンパイルしてそのバイナリをクラスパスに動的追加することで高速なreadが可能になると思われる. また, 非同期IOを用いて, その間に別の処理を行うこともscalaだと割と簡単なのでそれによる高速化もできる.

選択方法

個人的には, 静的型安全であるとか色々な理由でscalaプログラムを使いたい. そしてそれがだめならJSON, propertiesファイルの順で使いたい. 従って, 設定ファイルの選択方法は次のような感じかなぁ.

  • そもそも起動に時間がかかるアプリケーションである(IDEなど). または, 設定ファイル読み込み以外にボトルネックがある(e.g. ネットワークアクセス)
  • Yes
    • scalaプログラム + 非同期IO
  • No
    • 設定ファイルはめったに変更されない.
    • Yes
      • scalaプログラム + 事前コンパイル
    • No
      • シェルスクリプトからも読み込む必要がある.
      • Yes
        • propertiesファイル
      • No
        • JSONフォーマット