CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-lang-modules--scala-collection-compat

A library that makes some Scala 2.13 APIs available on Scala 2.11 and 2.12, facilitating cross-building Scala 2.13 and 3.0 code on older versions

Pending
Overview
Eval results
Files

resource-management.mddocs/

Resource Management

Utilities for automatic resource management using the Using API, enabling safe handling of resources that need to be closed after use.

Core Imports

import scala.util.Using

Using Object

object Using {
  def apply[R: Releasable, A](resource: => R)(f: R => A): Try[A]
  
  object Manager {
    def apply[A](f: Manager => A): Try[A]
  }
}

trait Releasable[-R] {
  def release(resource: R): Unit
}

Basic Resource Management

Single Resource Management

Automatically manages a single resource using Using.apply.

def apply[R: Releasable, A](resource: => R)(f: R => A): Try[A]

Usage Example:

import java.io.{BufferedReader, FileReader}
import scala.util.{Try, Using}

val lines: Try[Seq[String]] =
  Using(new BufferedReader(new FileReader("file.txt"))) { reader =>
    Iterator.continually(reader.readLine()).takeWhile(_ != null).toSeq
  }

Multiple Resource Management

For managing multiple resources simultaneously, use Using.Manager.

object Manager {
  def apply[A](f: Manager => A): Try[A]
  
  trait Manager {
    def apply[R: Releasable](resource: R): R
  }
}

Usage Example:

import java.io.{BufferedReader, FileReader}
import scala.util.{Try, Using}

val lines: Try[Seq[String]] = Using.Manager { use =>
  val r1 = use(new BufferedReader(new FileReader("file1.txt")))
  val r2 = use(new BufferedReader(new FileReader("file2.txt")))
  val lines1 = Iterator.continually(r1.readLine()).takeWhile(_ != null).toSeq
  val lines2 = Iterator.continually(r2.readLine()).takeWhile(_ != null).toSeq
  lines1 ++ lines2
}

Releasable Trait

The Releasable type class defines how resources should be released.

trait Releasable[-R] {
  def release(resource: R): Unit
}

Built-in Instances:

  • AutoCloseable (Java resources like streams, readers, writers)
  • Custom releasable instances can be defined implicitly

Custom Releasable Example:

case class DatabaseConnection(url: String) {
  def close(): Unit = println(s"Closing connection to $url")
}

implicit val dbReleasable: Releasable[DatabaseConnection] = 
  (resource: DatabaseConnection) => resource.close()

val result: Try[String] = Using(DatabaseConnection("jdbc:...")) { conn =>
  "Query result"
}

Error Handling

The Using utilities wrap all operations in Try, providing safe error handling:

  • Success: Resource is used and properly released
  • Failure: Captures both operation failures and resource release failures
  • Exception Handling: Ensures resources are released even if exceptions occur
import java.io.FileInputStream
import scala.util.{Try, Success, Failure}

val result: Try[Int] = Using(new FileInputStream("data.txt")) { stream =>
  stream.available()
}

result match {
  case Success(size) => println(s"File size: $size bytes")
  case Failure(exception) => println(s"Error: ${exception.getMessage}")
}

Resource Release Order

When using Using.Manager, resources are released in reverse order of acquisition:

Using.Manager { use =>
  val resource1 = use(openResource1())  // Released last
  val resource2 = use(openResource2())  // Released second  
  val resource3 = use(openResource3())  // Released first
  // ... use resources
}

Availability

Note: The Using utility is only available in the Scala 2.11 compatibility version. In Scala 2.12+ and 2.13+, it's part of the standard library.

Complete Example

import java.io.{FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream}
import scala.util.{Try, Using}

def copyFile(source: String, dest: String): Try[Unit] = Using.Manager { use =>
  val input = use(new BufferedInputStream(new FileInputStream(source)))
  val output = use(new BufferedOutputStream(new FileOutputStream(dest)))
  
  val buffer = new Array[Byte](8192)
  var bytesRead = 0
  
  while ({
    bytesRead = input.read(buffer)
    bytesRead != -1
  }) {
    output.write(buffer, 0, bytesRead)
  }
  
  output.flush()
}

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-lang-modules--scala-collection-compat

docs

annotation-backports.md

backported-collections.md

collection-extensions.md

collection-factories.md

index.md

iterator-size-ops.md

java-interop.md

map-extensions.md

method-chaining.md

option-converters.md

resource-management.md

string-parsing.md

tile.json