Twitter製のScala向けConfigライブラリのutil-evalが素敵すぎる

現在作ってるアプリで設定ファイルを作りたくなったので、Scalaで人気の設定ファイルライブラリであるutil-evalを使ってみた。

このライブラリの特徴は何と言っても設定ファイルをScalaで記述できること。XMLYAML, プロパティファイルじゃなくて内部DSLです。とは言うものの、Railsrubyで設定を記述しているし、仕事ではPHP使って似たようなことはしているので、これだけだと絶賛するほどじゃなかったり。重要なのはScalaが静的型付け言語だと言うことです!(キリ

それの何が嬉しいの? と言われそうなので、皆さん想像してみてください。モード切替でマジックナンバーや文字列で指定している状況を。入力間違えにより容易に謎のエラーとなります。でも、util-evalならenumやcase classを使うことで特定の値以外が入力されたらコンパイルエラーにできます。もちろん、文字列や整数もしかり。つまり、設定値の妥当性検証をコンパイラ任せにできるのですね。素晴らしい。

もちろん、内部DSLなので構造を持つ設定値もシンプルに記述できます。case classを使えば定義も楽チン。

というわけで、実際の使い方は以下のとおり。

1. SBTでインストール

まずはsbtでインストールします。build.sbtに下記を追記。

libraryDependencies += "com.twitter" % "util-eval" % "1.12.13" withSources()
resolvers += "T repo" at "http://maven.twttr.com/"

こちらを設定して「sbt update」すればOKです。ググるScala 2.9には対応していないという記事がよく見つかりますが、バージョンが上がったせいか、特に問題なく利用できています。あと、今回は確認してないですがリポジトリ見てみるとv2.0とかv3.0とかもすでに存在はしてました。

2. 定義ファイルの作成

設定値の定義ファイルとなるtraitを作成します。サンプルは下記の通り.

package cn.orz.pascal.scala

trait MyConfig {
  val title:String

  val buffSize:Int

  case class AmazonPAAConfig(accessKeyId:String, secretKey:String, associateTag:String)
  val amazonPAA:AmazonPAAConfig

  object ValidationType extends Enumeration { val Strict, Simple = Value }
  val validationType:ValidationType.Value
}

3. 設定ファイルの作成

定義ファイルに基づいて実際の設定ファイルを作る.  今回はconfigディレクトリ当たりに作った

mkdir config
vim config/config.scala

設定内容は下記のように書けます。

import cn.orz.pascal.scala.MyConfig
      
new MyConfig {
  val title = "Hello World."
  val buffSize = 1024
  val amazonPAA = AmazonPAAConfig (
    accessKeyId  = "AAAAAAAAAAAAAAAA",
    secretKey    = "AAAAAAAAAAAAAAAX2AAAAAAAAAAAA",
    associateTag = "test"
  )
  val validationType = ValidationType.Simple
} 

4. 設定ファイルの読み込み

設定ファイルはEvalオブジェクトを使って読み込みます。こんな感じ。

import com.twitter.util.Eval
import cn.orz.pascal.scala.MyConfig

val config = Eval[MyConfig](new java.io.File("config/Config.scala"))

// あとは普通にフィールドアクセスすればOK.
config.title
config.buffSize
config.amazonPAA.accessKeyId
config.validationType

こんな感じで利用方法もシンプルなので、かなり良い感じです。なお、設定ファイルは動的に読まれてEvalされます。ここで、config.scalaの内容がMyConfigとマッチしてなければコンパイルエラーが出るし、読み込んだ値を整数とかにパースしなおす手間も不要です。


Webアプリでwarを使う時とか、jarの中の設定ファイルを読むときは、getResourcesでパス取得かなぁ、と思ってたけど、別に、静的に組み込むならこのライブラリ使わなくても普通にコンパイルしてしまえばいい気がした。パスの指定も不要になるし。

まあ、何にしてもこのライブラリ自体は実に良い感じ。16桁の文字列を表す型とか作れば、さらに便利さが増すんじゃないかな?

 

参考:
http://blog.youhei.jp/scala-util-eval
http://d.hatena.ne.jp/kxbmap/20111208/1323355184