ローンパターンでリソースのクローズを確実に

ローンパターン

Scalaでは関数をオブジェクトとして扱えるため、以下のような関数を考えることができる

  def withWriter(filename: String)(op: Writer => Unit) {
    val writer = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(filename),"UTF-8"))
    try {
      op(writer)
    } finally {
      writer.close()
    }
  }

このwithWriter関数は以下の2つの引数をとる

  1. String 型のファイル名
  2. Writer 型の引数を受け取り、Unit 型(つまり戻り値なし)を返す関数

withWriter関数内部では、指定されたファイル名でストリームを作成し、外部から与えられた関数にwriterを貸出し、その後、クローズ処理を行っている。

この関数は以下のように呼び出すことができる。

  withWriter("test.txt"){
    writer => writer.write("this is sample")
  }

2つ目の引数として、与えられたwriterに書き込みを行う関数を渡している。貸し出した(loan)リソースに処理を行うため、ローンパターンと呼ばれる。

このような関数を用いることで、Javaで必要だった、あの忌々しいfinally-close構文が不要となる。

サンプル全文

import java.io._

object Sample {

  def main(args : Array[String]) : Unit = {
    withWriter("test.txt"){
      writer => writer.write("this is sample")
    }
  }

  def withWriter(filename: String)(op: Writer => Unit) {
    val writer = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(filename),"UTF-8"))
    try {
      op(writer)
    } finally {
      writer.close()
    }
  }
}

補足

前述のサンプルではカリー化されているが、以下のような書き方もできる。

  withWriter("test.txt", writer => writer.write("this is sample"))

  def withWriter(filename: String, op: Writer => Unit) {
    ・・・
  }