コールバックの引数の名前に制約が
Java8 のラムダになると、
「外側で宣言されている変数と同じ名前の変数をラムダで宣言できない」
という挙動になるようです。
MemberCB cb = new MemberCB();
cb.query().existsPurchaseList(subCB -> {
subCB.query().existsPurchaseDetailList(subCB -> {
...
});
});
ちょっと違う状況を想像
今までの無名インナークラスなら隠蔽になっていましたが、
ラムダだとコンパイルエラーになるそうです。
まあ、紛らわしいのがなくなって安全になった、
というのかもしれませんが、
ぼくはちょっと違う状況を想像してしまいました。
MemberCB cb = new MemberCB();
cb.query().existsPurchaseList(subCB -> {
subCB.query().existsPurchaseDetailList(subCB2 -> {
subCB.query().set...();
});
});
こういうが結構あるんじゃないかなぁって。
というか、普通に cb を SubQuery の中で使っちゃうケースも...
MemberCB cb = new MemberCB();
cb.query().existsPurchaseList(subCB -> {
cb.query()...
});
「finalを付けなくても外側の変数が参照できる」
という新しい仕様によって、
なおさらこういう間違いが簡単に発生してしまいます。
なんか便利になったようで、逆に間違いが増えそうみたいな。
なので、ぶっちゃけ、このJava8の新しい仕様、
「あんまりうれしくないかも」って思っています。
外側のcb参照を例外にするオプションを
DBFluteにおいては、外側のcb参照をcallbackの中で
使うことは基本的にありません。(DreamCruise以外)
なので、万が一 SubQuery の中で外側の cb を呼んじゃったら
例外になるようなチェックオプションを付けられるようにしました。
DBFlute-1.1 : デフォルトで有効
DBFlute-1.0.x : オプションにて
既存コードにおいては、
万が一やっているところがあったら落ちちゃうので、
(ただ、そんなコードは直すべきですが...)
次にリリースされる 1.0.5F から利用できます。
isThatsBadTimingDetect = true
ちゃんと、DreamCruiseは利用できます。
厳密には、DreamCruiseを作ったCBはチェックされなくなります。
まあめったにないことなので、シンプルなロジックにしてしまいました。
それは、そうと、
subCB とかではなく、
purchaseCB みたいな名前を付けていく方がいいのかもですね。
別にそれによって間違いがなくなるわけではないですが。。。
(purchaseDetailCB を補完するときに、
ついつい purchaseCB を選んじゃうってのあるよなぁ...)
MemberCB cb = new MemberCB();
cb.query().existsPurchaseList(purchaseCB -> {
purchaseCB.existsPurchasePaymentList(paymentCB -> {
paymentCB.query().set...();
});
});