Last active
June 11, 2019 03:57
-
-
Save seraphy/b0b667295c967bb50b64b7bd16cac166 to your computer and use it in GitHub Desktop.
ScalaでTry-with-resourceの実装例。https://medium.com/@dkomanov/scala-try-with-resources-735baad0fd7d の実装例のテスト。類似の仕組みについては、 このあたりにまとまっている。http://www.ne.jp/asahi/hishidama/home/tech/scala/sample/using.html#h_loan_pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.example | |
import java.io.IOException | |
import org.junit.Test | |
import jp.seraphyware.example.ScalaTryWithResourcesExample._ | |
/** | |
* テストクラス | |
*/ | |
class ScalaTryWithResourceExampleTest { | |
/** | |
* クローズ時に例外を出せるテスト用リソース | |
* | |
* @param raiseError クローズ時に例外を出すか? | |
*/ | |
private class TestResource(private val raiseError: Boolean) extends AutoCloseable { | |
println("constructor") | |
override def close(): Unit = { | |
println("close") | |
if (raiseError) { | |
println("exception when closing!") | |
throw new RuntimeException("TEST=EXCEPTION") | |
} | |
} | |
} | |
@Test | |
def testBlockNorm(): Unit = { | |
println("★Loan patten★") | |
withResources(new TestResource(false)) { | |
_ => | |
} | |
} | |
@Test(expected = classOf[IOException]) | |
def testBlockExcept(): Unit = { | |
println("★Loan patten (exception)★") | |
withResources(new TestResource(false)) { | |
_ => throw new IOException("brake!!") | |
} | |
} | |
@Test(expected = classOf[IOException]) | |
def testBlockDblExcept(): Unit = { | |
println("★Loan patten (finally-exception)★") | |
withResources(new TestResource(true)) { | |
_ => throw new IOException("brake!!") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.seraphyware.example | |
import scala.util.control.NonFatal | |
/** | |
* Java7以降のTry-With-Resource構文と同等な処理のScalaでの実装例。 | |
* https://medium.com/@dkomanov/scala-try-with-resources-735baad0fd7d | |
*/ | |
object ScalaTryWithResourcesExample { | |
def withResources[T <: AutoCloseable, V](r: => T)(f: T => V): V = { | |
val resource: T = r | |
require(resource != null, "resource is null") | |
var exception: Throwable = null | |
try { | |
f(resource) | |
} catch { | |
case NonFatal(e) => | |
exception = e | |
throw e | |
} finally { | |
closeAndAddSuppressed(exception, resource) | |
} | |
} | |
private def closeAndAddSuppressed(e: Throwable, resource: AutoCloseable): Unit = { | |
if (e != null) { | |
try { | |
resource.close() | |
} catch { | |
case NonFatal(suppressed) => | |
e.addSuppressed(suppressed) | |
} | |
} else { | |
resource.close() | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment