autoCloseScope

inline fun <A> autoCloseScope(block: AutoCloseScope.() -> A): A(source)

The AutoCloseScope DSL allows for elegantly working with close-ables, without having to worry about intermediate errors, composing them, or keeping track of different close-ables and when they need to be closed.

Often when working with multiple AutoCloseable, Closeable from Java we need to use multiple nested use blocks and this can become tedious. An example below for copying files in Java:

Scanner("testRead.txt")
.use { scanner ->
Printer("testWrite.txt")
.use { printer ->
for(line in scanner) {
printer.print(line)
}
}
}

We can also write this code as follows:

autoCloseScope {
val scanner = install(Scanner("testRead.txt"))
val printer = install(Printer("testWrite.txt"))
for(line in scanner) {
printer.print(line)
}
}

In the snippet above, Scanner, and File just like the nested use blocks

This also works with suspend, since autoCloseScope is inline however if you need to take into inspect cancellation then you need to use ResourceScope from Arrow Fx Coroutines. So both AutoCloseScope, and ResourceScope behave correctly when encountering cancellation, by closing the source, but ResourceScope allows inspecting complete, failure, and cancellation in the finalizer.

This DSL works very well with Kotlin's experimental feature context receivers, soon called context parameters. We can write the same code from above as a function:

context(AutoCloseScope)
fun copyFiles(input: String, output: String) {
val scanner = install(Scanner(input))
val printer = install(Printer(output))
for(line in scanner) {
printer.print(line)
}
}