try-catch-finally を scala.util.control.Exception で書いてみる
11 月 10 日に daimon.scala Scala School#1 に参加してきました。
Scala School (http://twitter.github.com/scala_school/basics2.html) の Exceptions のところ、try-catch-finally を使う例に対して「優れたプログラミングスタイルの例ではありません。」(@seratch による日本語訳はこちら http://d.hatena.ne.jp/seratch2/20111101/1320162713) とあるけどじゃあ優れたスタイルってなんだよという話がありました。もしかしたら scala.util.control.Exception で書くのが良いかもという意見があり、僕もそう思ったので実装してみました。
Scala School の例
val result: Int = try { remoteCalculatorService.add(1, 2) } catch { case e: ServerIsDownException => { log.error(e, "the remote calculator service is unavailble. should have kept your trustry HP.") 0 } } finally { remoteCalculatorService.close() }
scala.util.control.Exception を使って書いてみた
import scala.util.control.Exception._ class ServerIsDownException extends Exception object A extends App { val remoteCalculatorService = new AnyRef { def add(a: Int, b: Int): Int = { a + b match { case odd if odd % 2 == 1 => odd case _ => throw new ServerIsDownException } } def close {} } val log = new AnyRef { def error(t: Throwable, m: String) { println(m) } } def add(a: Int, b: Int): Int = { catching(classOf[ServerIsDownException]). andFinally { remoteCalculatorService.close }. either { remoteCalculatorService.add(a, b) } match { case Right(x) => x case Left(t)=> { log.error(t, "the remote calculator service is unavailble. should have kept your trustry HP.") 0 } } } println("1 + 2 =" + add(1, 2)) println("1 + 1 =" + add(1, 1)) }
んー、わかりにくいかな?
scala.util.control.Exception は
ignoring(classOf[SQLException]) opt conn.close
とかやるときは try-finally より簡潔に書けるけど、catch 節の表現はわかりにくくなるかも?