Groovy使いがScalaを書く際の注意点(その1:defに気をつけろ)
このシリーズの一覧はこちら
はじめに
昨日(2011-02-19)に第2回Scala道場に参加してきたわけですが、コーディング最中に一点はまったことがあったのでメモしておく。
はまった点
/* DishOrderSheetTest.scala */ package dishs object DishOrderSheetTest { def main(args: Array[String]): Unit = { var os: DishOrderSheet = new DishOrderSheet(800) // <- ココ注目! var ios: IDishOrderSheet = os.takeOrderSheet System.out.println("1:" + ios.getOrderValue) os.setOrderId("k.kano_vip") System.out.println("2:" + ios.getOrderValue) } }
上記でココ注目!とした部分をはじめ、以下のように書いてしまっていました。
def os = new DishOrderSheet(800)
そうです、defです。Groovyでは変数だろうとメソッドだろうと宣言時はいつでもdef♪ですよね。ところがScalaだとdef関数宣言の時で、変数はvarやvalを使ってね、となっている。
ということで、上記例のようにdefで右辺をクラスをnewするように書いてしまうと、毎回新しいクラスがnewされて返ってきちゃう、言うなれば簡易ファクトリメソッドだ!となってしまうわけですね。
よって、osにアクセスするたびにnewされてしまって、その後の以下の部分でosで保持してたインスタンスに対してsetOrderIdしたかったんですが、期待した動作にならなかったわけです。
os.setOrderId("k.kano_vip")
みたいな感じになってしまってたわけですね。
まとめ
Groovy使いはScalaを書くときはdefの使いどころを見極めるべし。