Groovy入門して躓きメモ
Java→Groovy初日で出会ったエラーたちやメモたち。 syntaxもよくわからない中で出会って、解決するのに慣れなかったのでメモしておく。
メソッドの呼び出し間違い
メソッドの呼び出しが間違った時
Caught: groovy.lang.MissingMethodException: No signature of method: hogepackage.hogefile.hogemethod() is applicable for argument types: (java.math.BigDecimal, java.util.ArrayList, groovy.sql.Sql) values: ...
特にクロージャの中でエラーが起きるとクロージャのどこでそれが起きているのかよくわからなくて慣れるまで時間がかかった。
変数の宣言のスコープ
http://d.hatena.ne.jp/Kazuhira/20120318/1332083318
before
def sql = Sql.newInstance() Map.each{k,v-> searchUuidByUser(k,v,sql) }
eachの中からsqlは呼び出せない。
Caught: groovy.lang.MissingPropertyException: No such property: sql for class: hogepackage.hogefile groovy.lang.MissingPropertyException: No such property: sql for class: hogepackage.hogefile
after
sql = Sql.newInstance() Map.each{k,v-> searchUuidByUser(k,v,sql) }
def をつけているとクロージャ内やメソッド内から呼び出せない。
列名が無効
before
def SELECT_USER_POINT_HISTORY = "SELECT ID,POINT,INSERT_AT from POINT_HISTORY where ID = $userId ORDER BY INSERT_AT" List<Point> pointList = new ArrayList() sql.eachRow(SELECT_USER_POINT_HISTORY){ Point dto = new Point() dto.type = it.type dto.point = it.point dto.insertAt = it.insert_at pointList.add(dto) }
警告: Failed to execute: SELECT ID,POINT,INSERT_AT from POINT_HISTORY where ID = ? AND TYPE != 0 ORDER BY INSERT_AT because: 列名が無効です。 Caught: java.sql.SQLException: 列名が無効です。 java.sql.SQLException: 列名が無効です。
てっきりSQLが悪いのかと思ってタイポかどうか必死に探したけどSQLが悪いわけじゃなかった
after
def SELECT_USER_POINT_HISTORY = "SELECT ID,POINT,TYPE,INSERT_AT from POINT_HISTORY where ID = $userId ORDER BY INSERT_AT" List<Point> pointList = new ArrayList() sql.eachRow(SELECT_USER_POINT_HISTORY){ Point dto = new Point() dto.type = it.type dto.point = it.point dto.insertAt = it.insert_at pointList.add(dto) }
eachRowの中で参照しているit.typeがselectするものに含まれてないため。 エラー行数をよく見るとit.typeを使っている行を指しているのでわかる
for文の抜けかた
https://stackoverflow.com/questions/3049790/can-you-break-from-a-groovy-each-closure 次のイテレートに入るならeachのままcontinueしてもOK そもそもループを中止したい時(Javaでいうbreakをしたい時)はfindにしてその中でtrueを返してループを終わりにする
pointList.find{ Data data = new Data(); if(nowPoint<it.point){ //breakと同じ。ループを抜ける return true; }else{ //continueと同じ。 return false; } }