I\'m using a Java-API which heavily uses the Autoclosable-Interface and thus in Java try-with-resources. However in Java you can specify
Yet another approach for this:
val CloseableContext = ThreadLocal>()
inline fun scopeDef(inScope: () -> Unit) {
val oldContext = CloseableContext.get()
val currentContext = mutableListOf()
CloseableContext.set(currentContext)
try {
inScope()
}
finally {
for(i in (currentContext.size - 1) downTo 0) {
try {
currentContext[i].close()
}
catch(e: Exception) {
// TODO: Record as suppressed exception
}
}
CloseableContext.set(oldContext)
}
}
fun autoClose(resource: T): T {
CloseableContext.get()?.add(resource) ?: throw IllegalStateException(
"Calling autoClose outside of scopeDef is forbidden")
return resource
}
Usage:
class Close1(val name: String): AutoCloseable {
override fun close() {
println("close $name")
}
}
fun main(args : Array) {
scopeDef {
val c1 = autoClose(Close1("1"))
scopeDef {
val c3 = autoClose(Close1("3"))
}
val c2 = autoClose(Close1(c1.name + "+1"))
}
}
Output:
close 3
close 1+1
close 1