groovyでJSON文字列を作ってみる

groovy勉強のメモを残していきたいと思います。

## 環境

Windwows上でVM入れたりしていますが、Git bash 上で動かす方が多いと思います。
groovyは 2.4.7 でやっています。
groovyのソースはGGTSやEclipse neon上でいじっていますが、フリーズしたら vim でいじります。

## はじめに

家の本が溢れ出して読むよりも、買うペースが上まった時から本をほぼ買うことをやめたんですよねぇ。
漫画本、小説もしかり、当然技術本も。
古いですが電子に移行するためにkindle3を買ったのがアメリカの amazon からだったような記憶がありますねぇ(^ ^;
技術本なんて厚いですから部屋のスペースをとっちゃうんですよねぇ。
ということで本を買わなくなって、適当にネットで勉強するようになったために陥ったような問題の解決の記録として残して置きたいと思います。

## JSON作成

Web関係やってるとJSONって必須になってきますよね。
そのときにgroovyでJSONを作成するための勉強の記録です。

### オブジェクトリテラル

昔どこかでPHPはJSONである、的な記事を読んだ事があるんですよねぇ。
その時に思ったのは結局オブジェクトリテラルがあって、マップとリスト（配列）がかければ JSON っていいのかな？
ってことだったんですよね。

```groovy
def obj = [
  'aaa': 'string',
  'bbb': 'string',
  'ccc': [ "a0", "a1", "a2"],
  'ddd': [
    'hoge': "piyo",
  ],
]
def json = new groovy.json.JsonBuilder()
json(obj)
println json.toPrettyString()
```

JsonBuilder 使うと PHP で書いてたのが簡単にできるのねーって納得してみた頃。

### 文字列

オブジェクトから書けてOKってなったら次は素のJSONから作ってみましょうってなりますねぇ(^ ^)

```groovy
def jsonText = $/
{
  "aaa": "string",
  "bbb": 0,
  "ccc": [
      "a0",
      "a1",
      "a2"
  ],
  "ddd": {
      "hoge": "piyo"
  }
}
/$

def sluper = new JsonSlurper()
def object = sluper.parseText(jsonText)

def json = new JsonBuilder()
json(object)
println json.toPrettyString()
```

ここでついでに groovy のヒアドキュメントも勉強してましたね。ヒアドキュメントは
http://d.hatena.ne.jp/Kazuhira/20130715/1373878511
こちらが結構丁寧に説明されてますでしょうか？
伝統的なshとかのとちょっと違うので最初はとまどっちゃいますね。javaにも欲しいですねー。

### JsonBuilder & ConfigSlurper

やりはじめて調べていると、JsonBuilder 使うとなんか違う書き方で書ける的な文章も色々でてきてきます。
http://www7b.biglobe.ne.jp/~makandat/groovy/groovy/JsonBuilder.html
ぐぐってこのあたりとか読み始めて、、、
はっ？(-_-;
ってなってきたんですよねぇ。

なんか適当にやってた gradle 的なのねー。＜逆なんですけど（笑）
でも意味わからないしー
そんな日々。
多分全部ちゃんと本を読んで順番に勉強してないせいなんだと思いますけどねぇ(^ ^;

### JsonBuilderで行単位に値を書く

まずはサイトの抜粋的なものを。

```groovy
def json = new groovy.json.JsonBuilder()
def root = json.obj {
  aaa 'string'
  bbb 0
  ccc 'a0', 'a1', 'a2'
  ddd(hoge: 'piyo')
}
println json.toPrettyString()
```

結果はこんなですね。ちゃんとしたJSONになってますねぇ。

```JSON
{
    "obj": {
        "aaa": "string",
        "bbb": 0,
        "ccc": [
            "a0",
            "a1",
            "a2"
        ],
        "ddd": {
            "hoge": "piyo"
        }
    }
}
```

ここで適当な勉強してないので疑問が３つも発生！

1. obj ってメソッドじちゃうの？
2. クロージャの中はなんでなんでキー・バリューで書けるの？
3. dddだけまた違うじゃん！？なんで！(T-T)

基本的にゲームもマニュアル読んでから始める派なので、言語も勉強しながらよりは一読してからやる派なんですよねぇ。
だんだんそれができなくなったのは複雑になってきたの頭がついていかないのか...(多分後者)。
本読まないでやってるのでしょうがないんですけど、自分の知識だけで悩んでも悩みすぎるとハゲるだけなので、一周りしたら悩まないようにします。まずはドキュメントよんでみました。
http://docs.groovy-lang.org/latest/html/gapi/groovy/json/JsonBuilder.html
javadoc的なものですねー。
上のブログと同じようなことが書いてある...(- -;うぬー

少しぐーぐる先生に頼ります。
http://dev.classmethod.jp/server-side/groovy-server-side/how-to-write-groovy-dsl/
Groovy DSLって記法も groovy構文なんですと。
DSLってよくわからなかったんですけど、JCLやshみたいなものをいうんでうすね（とりあえずそう覚えておきましょう）。

ふむふむ。ここで２のキー・バリューで書けるが解決しました。

```groovy
aaa "string"
```
thisのaaaメソッドに引数 "string"を渡すってことですね！？
え、でもお前、aaaメソッドないじゃん？
はてー。とドキュメント読み返しているとJsonBuilderのドキュメントにinvokeMethodっていうのがあるのに気が付きました。

またぐーぐる先生に頼ります。
http://d.hatena.ne.jp/Groovy/20071123/1195827667
groovyではこのメソッドが、定義されていないメソッドを呼び出した時に呼び出されると！
おおー。２と１が解決ですね。
いずれにしろ、クロージャのなかで this が JsonBuilder になっているのがとっても大事な感じですね(^ ^)

ここまでわかると三番目の ddd だけの問題は、ddd メソッドを括弧つき呼び出しでマップを渡したいってことがわかりました。
複数行で括弧をつけなくても、バリューの最後にカンマをつければ記述できましたが、最後のカンマは省略できませんでしたね。
最近はカンマつけて記述するほうが（自分的に）主流なので括弧ついて記述したほうがいい感じかもです(^ ^)


### ConfigSlurperで行単位に値を書く

いろいろ調べていたらConfigSlurperで書いてパースするやり方もありましたですね。
http://npnl.hatenablog.jp/entry/20101121/1290356773
これはちょっとおもしろい書き方ですね。
プロパティチックにかけるけども、これもシンタックスなんですね。

```groovy
def json = new groovy.json.JsonBuilder()
def obj = new ConfigSlurper().parse("""
aaa = 'string'
bbb = 0
ccc = [ 'a0', 'a1', 'a2' ]
ddd.hoge = 'piyo'
""")
json(obj)
println json.toPrettyString()
```

ここでも大事なのは this が何かですよね（parseの中ではscrpit*になっていてちゃんとわかりませんでしたが）。

## さいごに

スクリプトないで書く時に括弧に一行とられるのが結構嫌で、行単位でかけるといい感じですね。
ConfigSlurperみたいにプロパティチックに書くと、外部ファイル化したくなって、そうなると独自シンタックスは嫌になって
結局ファイルはJSONって感じなパラドックス的な何かを感じます。

JSONの勉強でシンタックスの謎が少しとけたのがメリットでした。
また勉強して書き方追加できたらと思います。