or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-backports.mdbackported-collections.mdcollection-extensions.mdcollection-factories.mdindex.mditerator-size-ops.mdjava-interop.mdmap-extensions.mdmethod-chaining.mdoption-converters.mdresource-management.mdstring-parsing.md

resource-management.mddocs/

0

# Resource Management

1

2

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

3

4

## Core Imports

5

6

```scala

7

import scala.util.Using

8

```

9

10

## Using Object

11

12

```scala { .api }

13

object Using {

14

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

15

16

object Manager {

17

def apply[A](f: Manager => A): Try[A]

18

}

19

}

20

21

trait Releasable[-R] {

22

def release(resource: R): Unit

23

}

24

```

25

26

## Basic Resource Management

27

28

### Single Resource Management

29

30

Automatically manages a single resource using `Using.apply`.

31

32

```scala { .api }

33

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

34

```

35

36

**Usage Example:**

37

```scala

38

import java.io.{BufferedReader, FileReader}

39

import scala.util.{Try, Using}

40

41

val lines: Try[Seq[String]] =

42

Using(new BufferedReader(new FileReader("file.txt"))) { reader =>

43

Iterator.continually(reader.readLine()).takeWhile(_ != null).toSeq

44

}

45

```

46

47

### Multiple Resource Management

48

49

For managing multiple resources simultaneously, use `Using.Manager`.

50

51

```scala { .api }

52

object Manager {

53

def apply[A](f: Manager => A): Try[A]

54

55

trait Manager {

56

def apply[R: Releasable](resource: R): R

57

}

58

}

59

```

60

61

**Usage Example:**

62

```scala

63

import java.io.{BufferedReader, FileReader}

64

import scala.util.{Try, Using}

65

66

val lines: Try[Seq[String]] = Using.Manager { use =>

67

val r1 = use(new BufferedReader(new FileReader("file1.txt")))

68

val r2 = use(new BufferedReader(new FileReader("file2.txt")))

69

val lines1 = Iterator.continually(r1.readLine()).takeWhile(_ != null).toSeq

70

val lines2 = Iterator.continually(r2.readLine()).takeWhile(_ != null).toSeq

71

lines1 ++ lines2

72

}

73

```

74

75

## Releasable Trait

76

77

The `Releasable` type class defines how resources should be released.

78

79

```scala { .api }

80

trait Releasable[-R] {

81

def release(resource: R): Unit

82

}

83

```

84

85

**Built-in Instances:**

86

- `AutoCloseable` (Java resources like streams, readers, writers)

87

- Custom releasable instances can be defined implicitly

88

89

**Custom Releasable Example:**

90

```scala

91

case class DatabaseConnection(url: String) {

92

def close(): Unit = println(s"Closing connection to $url")

93

}

94

95

implicit val dbReleasable: Releasable[DatabaseConnection] =

96

(resource: DatabaseConnection) => resource.close()

97

98

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

99

"Query result"

100

}

101

```

102

103

## Error Handling

104

105

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

106

107

- **Success**: Resource is used and properly released

108

- **Failure**: Captures both operation failures and resource release failures

109

- **Exception Handling**: Ensures resources are released even if exceptions occur

110

111

```scala

112

import java.io.FileInputStream

113

import scala.util.{Try, Success, Failure}

114

115

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

116

stream.available()

117

}

118

119

result match {

120

case Success(size) => println(s"File size: $size bytes")

121

case Failure(exception) => println(s"Error: ${exception.getMessage}")

122

}

123

```

124

125

## Resource Release Order

126

127

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

128

129

```scala

130

Using.Manager { use =>

131

val resource1 = use(openResource1()) // Released last

132

val resource2 = use(openResource2()) // Released second

133

val resource3 = use(openResource3()) // Released first

134

// ... use resources

135

}

136

```

137

138

## Availability

139

140

**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.

141

142

## Complete Example

143

144

```scala

145

import java.io.{FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream}

146

import scala.util.{Try, Using}

147

148

def copyFile(source: String, dest: String): Try[Unit] = Using.Manager { use =>

149

val input = use(new BufferedInputStream(new FileInputStream(source)))

150

val output = use(new BufferedOutputStream(new FileOutputStream(dest)))

151

152

val buffer = new Array[Byte](8192)

153

var bytesRead = 0

154

155

while ({

156

bytesRead = input.read(buffer)

157

bytesRead != -1

158

}) {

159

output.write(buffer, 0, bytesRead)

160

}

161

162

output.flush()

163

}

164

```