Groovy style guide in ja

どっかにあるかもしれんね。

## groovy style guide in ja

### 概要
http://groovy-lang.org/style-guide.html
の雑な和訳をしたい

### 1. No セミコロン
C/C++/C#/Javaのバックグラウンドを持つ人はよくセミコロンを使っていたし、Groovyも99% javaのシンタックスをサポートしているので使用できる。がgroovyでは削除できるし
慣例的なそれを削除できる。

### 2. Returnはオプションです
groovyでは関数のbodyの最後のステートメントはreturnがなくとも戻り値として評価される。特に短い関数やクロージャは削除するのが良いだろう
ただ下記の例のような場合最後のステートメントの前に改行をするか、returnをつけるとより見やすくなるだろう。

```
def props() {
    def m1 = [a: 1, b: 2]
    m2 = m1.findAll { k, v -> v % 2 == 0 }
    m2.c = 3
    m2
}
```

注意しておくべきなのは、```def```で定義された場合で、最後のステートメントが戻り値として返ってくるので、voidかその他のtypeのような特定の方を使ったほうが良いだろう。

後```if/else```,```try/catch```のようなステートメントも戻り値を返します。下記のサンプルコードを参考にしてください。

```
def foo(n) {
    if(n == 1) {
        "Roshan"
    } else {
        "Dawrani"
    }
}

assert foo(1) == "Roshan"
assert foo(2) == "Dawrani"
```

### 3. Defとtype

```def``` と```type```両方共使えるけどその場合、```def```って余分だから```def```か```type```どちらかを使うようにして。

goorvyにおける```def```とは```Object```です。
(そのためdefで定義した関数はなんでも戻り値を取れるしなんでも引数をとれる)

defを使う場合、こう書かずに

```
void doSomething(def param1, def param2) { }
```

こう書きましょう

```
void doSomething(param1, param2) { }
```

でも、最後で言うけど、型は指定したほうが良いよ。IDEとかあるでしょ。
あとコンストラクタのdefは余分だよ

### 4. 何もしなければPublic
Groovyは基本publicの修飾子をつけているので、publicにしたければ何も指定しなくても良いよ。

packageスコープを気にするかもしれないけど、デフォルトではgroovyはサポートしてないからpublicを省略できる。
まあでも使いたかったらこうすればいい

```
class Server {
    @PackageScope Cluster cluster
}
```
### 5. 括弧を省略
トップレベルの括弧は省略できる。(するべきとは書いていないような気がする)
下記のようなクロージャの場合は三番目を選択するべき

```
list.each( { println it } )
list.each(){ println it }
list.each  { println it }
```

幾つかのケースで括弧は必要で,ネスト内で関数を呼ぶケースや、引数を呼ばずに関数を呼ぶケースなどが該当する

```
def foo(n) { n }
def bar() { 1 }

println foo 1 // won't work
def m = bar   // won't work
```

### 6. 第一級オブジェクトとしてのクラス
groovyでは```.class```は必要ない。

```
connection.doPost(BASE_URI + "/modify.hqu", params, ResourcesResponse.class)
```

ではなく

```
connection.doPost("${BASE_URI}/modify.hqu", params, ResourcesResponse)
```

こうかける

### 7. GettersとSetters

Groovyの場合gettersとsettersはpropertyと呼ぶ。javaのようにgetters/settersを呼ぶよりも、下のように呼ぶほうが良い

```
resourceGroup.getResourcePrototype().getName() == SERVER_TYPE_NAME
resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME

resourcePrototype.setName("something")
resourcePrototype.name = "something"
```

修飾子が無い変数に対してGroovyコンパイラはprivate変数とgetterとsetterを生成してくれる。

### 8. beans(class)の初期化
下記のようなclassに対して

```
class Server {
    String name
    Cluster cluster
}
```

下のように初期化せずに

```
def server = new Server()
server.name = "Obelix"
server.cluster = aCluster
```

こんな感じで初期化しよう

```
def server = new Server(name: "Obelix", cluster: aCluster)
```

### 9. 同じbean上繰り返し操作はwith()を使おう

```
server.name = application.name
server.status = status
server.sessionCount = 3
server.start()
server.stop()
```
serverがいっぱい出てきてダサいので

```
server.with {
    name = application.name
    status = status
    sessionCount = 3
    start()
    stop()
}
```

こう書こうぜ

### 10. Equalsと```==```

```==``` はGroovyの```is()```でGroovyの```==```は```equals()```よりもイケてる。

Objectの比較は ```==``` より ``` a.is(b) ```を使うべき
だが、```equals()```を使用して比較している場合Groovyの```==```を使ったほうが良い。
なぜなら```NullPointerException```に対応してくれるからだ。

```
status != null && status.equals(ControlConstants.STATUS_COMPLETED)
```
よりも

```
status == ControlConstants.STATUS_COMPLETED
```

こちらのほうが良いだろう

### 11.GStrings
Stringの連結とか改行について

```
throw new Exception("Unable to convert resource: " + resource)
```

とかけるところを
GStringだと、

```
throw new Exception("Unable to convert resource: $resource")
```
もかける。
こちらのほうが記述するのに楽じゃないだろうか。
遅延評価も```${-> resource}```のようにかけるし、Stringであることを明確にしたければ```toString()```と書くこともできる。

下記に遅延評価の例を書く

```
int i = 3

def s1 = "i's value is: ${i}"
def s2 = "i's value is: ${-> i}"

i++

assert s1 == "i's value is: 3" // eagerly evaluated, takes the value on creation
assert s2 == "i's value is: 4" // lazily evaluated, takes the new value into account
```

また継続文字として```\```が従来通り使えるが、triple quotesによてmultiline stringsも使用することできる。

また正規表現についてスラッシュが使えるのでそちらの方を使うべきである

```
assert "foooo/baaaaar" ==~ /fo+\/ba+r/
```
最後に文字列定数はsingle quotedを使用するべきである。
double quoteは明確にstring interpolationの場合使用するべき

#### single quoteとdouble quoteの違い

sigle quote: java Stringsを常に作成(${x}が使えない?)
doudle quote: interpolated variables(多分${x}みたいなやつのこと)がある場合GStringを作成して,それ以外はjava Stringsを作成する

### 12. データ構築のためのNative syntax
Groovyはlist,maps,regex,rangesのnative syntax構築方を提供しています。(訳自信なし)
下記のように構築できるので参考にして

```
def list = [1, 4, 6, 9]

// by default, keys are Strings, no need to quote them
// you can wrap keys with () like [(variableStateAcronym): stateName] to insert a variable or object as a key.
def map = [CA: 'California', MI: 'Michigan']

def range = 10..20
def pattern = ~/fo*/

// equivalent to add()
list << 5

// call contains()
assert 4 in list
assert 5 in list
assert 15 in range

// subscript notation
assert list[1] == 4

// add a new key value pair
map << [WA: 'Washington']
// subscript notation
assert map['CA'] == 'California'
// property notation
assert map.WA == 'Washington'

// matches() strings against patterns
assert 'foo' ==~ pattern
```

### 13. The Groovy Development Kit
色々なデータ構造をいじるためにGroovyではいろいろなmethodを提供している。
基本的なデータ構造をいじるときに[GDK APIドキュメント](http://beta.groovy-lang.org/gdk.html)を参考にすると良いかも。
(提案だと思います。)

### 14. switchのちから
GroovyのswitchはCっぽい言語のようなプリミティブ型しか許可されないswitchよりも強い。
Groovyのswitchは数多の型を許容する。

```
def x = 1.23
def result = ""
switch (x) {
    case "foo": result = "found foo"
    // lets fall through
    case "bar": result += "bar"
    case [4, 5, 6, 'inList']:
        result = "list"
        break
    case 12..30:
        result = "range"
        break
    case Integer:
        result = "integer"
        break
    case Number:
        result = "number"
        break
    case { it > 3 }:
        result = "number > 3"
        break
    default: result = "default"
}
assert result == "number"
```

```isCase()``` を使えば型の一致も確認できる。

### 15. 別名でImportできる

同じ名前のライブラリをインポートするとき別名を指定できるようになった。

```
import java.util.List as UtilList
import java.awt.List as AwtList
import javax.swing.WindowConstants as WC

UtilList list1 = [WC.EXIT_ON_CLOSE]
assert list1.size() instanceof Integer
def list2 = new AwtList()
assert list2.size() instanceof java.awt.Dimension

//　これもできるぞ
import static java.lang.Math.abs as mabs
assert mabs(-4) == 4
```

### 16. Groovy Truth

`null`,`void`,`zero`そしてemptyは`false`と評価され、それ以外は`true`

```
if (name != null && name.length > 0) {}
```

よりも

```
if (name) {}
```

こうかこう

### 17. 安全なGraph navigation

javaの場合、複雑なifを書く場合nulをチェックするために下記のようなコードを書いていたかも

```
if (order != null) {
    if (order.getCustomer() != null) {
        if (order.getCustomer().getAddress() != null) {
            System.out.println(order.getCustomer().getAddress());
        }
    }
}
```

```?.``` を使えばすごくシンプルになる。

 ```
 println order?.customer?.address
 ```
 この場合```NullPointerException```を投げずに戻りとして```null```が返される。
 
### 18. Assert
 javaの場合assertを実施する場合有効化する必要があったが、Groovyの場合常に確認する。
 
 ```
 def check(String name) {
    // name non-null and non-empty according to Groovy Truth
    assert name
    // safe navigation + Groovy Truth to check
    assert name?.size() > 3
}
```

### 19. エルビス演算子

が使えます。(javaでもjava8から使えるようになったらしい。)

```
def result = name ?: "Unknown"
```

この場合nameがtrueの場合はnameを代入、falseの場合"Unknown"が代入される

### 20. 想定していない例外をCatchする場合

```
try {
    // ...
} catch (Exception t) {
    // something bad happens
}
```

ではなく

```
try {
    // ...
} catch (any) {
    // something bad happens
}
```

こうかこう

#### 注意
上記の書き方は全てのExceptionは補足できるが、Throwableで投げれるものは受け取れないのでThrowableなオブジェクトを受け取るには、明示的にThrowable オブジェクトをキャッチしよう。

### 21. 型についてのアドバイス
Groovyは強い型指定するか、defを使うかを決めさせる。

単純なルールとして他人が使うようなAPIは型指定をするべき。(型が違う引数を渡されるとか、良いドキュメントを作成できるし)
自分だけが使用するようなprivate関数は好きにしなさい。

誤字脱字、誤訳は多分いっぱいあるので雰囲気だけぜひ掴んでほしい