Scalaで設定ファイルを使いたい時どうしたらいいの?

August 30, 2011 - Scala

2011.08.31 kmizushimaさんから頂いたコメントを元に、下記の記述を修正&追記しました。

  • Twitterのutil-evalの一時ファイル生成について
  • AkkaのConfigファイルのパース手法について

TwitterのOAuthの鍵やDB接続情報など、アプリを書く上で環境によって切り替える設定が大抵の場合あると思います。普段使っているPHPの場合、設定を外部ファイルに書きだす場合、ini,yaml,xml,phpのいずれかを使うことが多いのですが、Scalaの場合、設定ファイルってどうするのか気になりました。

ということで、適当に思いついたライブラリやフレームワークがどのように対応しているのか調査。

ライブラリ

propertiesファイル

  • javaの古くから使われている
  • キーと値のみ設定可能
  • 依存関係がないので手軽。
  • すべてが文字列
  • 例えばこんな感じ

path/to/conf.properties

hoge = "moge"
val p = new java.util.Properties()
val config = p.load(new java.io.FileInputStream("path/to/conf.properties");
config.get("hoge") // "moge"

twitterのconfiggy

twitterのutil-eval

設定のtraitを定義

src/main/scala/com/restartr/utilSample/MyConfig.scala

package com.restartr.utilSample

trait MyConfig {
  val num: Int
  val str: String
}

実際の設定ファイルでは、設定のTraitを継承してインスタンス生成

※クラスインスタンスでなくても文字列やリストでもOK。

path/to/config/MyConfig.scala

import com.restartr.utilSample.MyConfig
new MyConfig {
  val num = 1
  val str = "san"
}

使いたい場所でEval。

val conf = Eval[MyConfig](new java.io.File("path/to/config/MyConfig.scala"))
conf.num // 1
conf.str // "san"

configrity

各種フレームワーク

以下のフレームワークはすべて独自実装でした。Propertiesじゃ役不足だし、かといってデファクトな設定用ライブラリがないからなのでしょうか。

akkaのconfig

  • akka.confとかがそれ。
  • 独自パーサーを使用
    • 70行程度のシンプルなパーサー
    • akka.config.ConfigParser
    • 正規表現で定義されてるScalaのパーザコンビネータ(RegexParsersを継承)で定義されている
      • ”{“と”}“で階層構造を表現
akka {
  cluster{
    name = "test-cluster"
  }
}
  • 使える型
    • 数値
    • 文字列
    • 真偽値(on/off , true/false)
    • リスト [1,2,3] / [“hoge”,“moge”]

play!frameworkのconfig

Lift

ざっと調べて使ってみたところ、手軽にやるならProperties、フレームワークを使うならそれに則り、厳密にやるならTwitterのEvalや、設定ファイルを読み書きできる独特なConfigrityなんかがよさそうです。

XMLは…まぁないでしょうね。