argonautを使ってみた
設定をXMLよりももっと簡単に記述して読み込みたい、という希望のもとにあれこれ調べるまでもなく、実際Jsonを使ってやってみるのが標準のようだ。Scala標準のJsonパーサーはどうやら使いにくいし今後無くなる方向だそうです。(こちら参照→標準ライブラリのJSONはScala2.11から非推奨になるので使ってる人は今すぐ使うのやめましょう - xuwei-k's blog)
関数型言語を勉強してるのなら、argonaut一択でしょう。と使い始めて、まず6.0.4ではScalazの7.1に対応していないので6.1-M6とか使いましょう。sbtではこんなふうに。
libraryDependencies ++= Seq("io.argonaut" %% "argonaut" % "6.1-M4")
また、Scalazのレポジトリをresolversに入れておかないと見つからないかもしれない。上記だけではsbtのupdate時にエラーになるときは、これも追加しましょう。
resolvers ++= Seq("Scalaz Bintray Repo" at "http:/dl.bintray.com/scalaz/releases")
多分これでargonautのquickstart→Argonaut: Purely Functional JSON in Scalaにある以下のがうまく動くはず。
カンマとか一個でも抜けてると動かないので細心の注意が必要です。
/* Below source code is copied from argonaut official page http://argonaut.io/doc/quickstart/ */ package argonaut.doc import scalaz._, Scalaz._ import argonaut._, Argonaut._ object QuickStartExample extends App { val input = """ [ { "name": "Mark", "age": 191 }, { "name": "Fred", "age": 33, "greeting": "hey ho, lets go!" }, { "name": "Barney", "age": 35, "address": { "street": "rock street", "number": 10, "post_code": 2039 }} ] """ // parse the string as json, attempt to decode it to a list of person, // otherwise just take it as an empty list. val people = input.decodeOption[List[Person]].getOrElse(Nil) // work with your data types as you normally would val nice = people.map(person => person.copy(greeting = person.greeting.orElse(Some("Hello good sir!")))) // convert back to json, and then to a pretty printed string, alternative // ways to print may be nospaces, spaces2, or a custom format val result = nice.asJson println(result.spaces4) assert(result.array.exists(_.length == 3)) } case class Address(street: String, number: Int, postcode: Int) object Address { // Define codecs easily from case classes implicit def AddressCodecJson: CodecJson[Address] = casecodec3(Address.apply, Address.unapply)("street", "number", "post_code") } case class Person(name: String, age: Int, address: Option[Address], greeting: Option[String]) object Person { implicit def PersonCodecJson: CodecJson[Person] = casecodec4(Person.apply, Person.unapply)("name", "age", "address", "greeting") }