0
# Utility Classes
1
2
General-purpose utility classes for common programming tasks, adapted for JavaScript environment constraints while maintaining full Scala API compatibility.
3
4
## Capabilities
5
6
### DynamicVariable
7
8
Thread-local-like variable support adapted for JavaScript's single-threaded environment, providing scoped value binding for functional programming patterns.
9
10
```scala { .api }
11
/**
12
* Variable with dynamic scope binding
13
* In JavaScript, provides stack-based scoping without true thread-local storage
14
* Values are scoped to execution context rather than threads
15
*/
16
class DynamicVariable[T](init: T) {
17
/** Get current value */
18
def value: T
19
20
/** Set new value */
21
def value_=(newval: T): Unit
22
23
/** Execute block with temporarily bound value */
24
def withValue[S](newval: T)(thunk: => S): S
25
26
/** String representation */
27
override def toString: String = s"DynamicVariable($value)"
28
}
29
30
object DynamicVariable {
31
/** Create DynamicVariable with initial value */
32
def apply[T](init: T): DynamicVariable[T] = new DynamicVariable(init)
33
}
34
```
35
36
**Usage Examples:**
37
38
```scala
39
import scala.util.DynamicVariable
40
41
// Configuration context
42
val currentUser = new DynamicVariable[String]("anonymous")
43
44
def getGreeting(): String = s"Hello, ${currentUser.value}!"
45
46
// Default behavior
47
println(getGreeting()) // "Hello, anonymous!"
48
49
// Scoped value binding
50
currentUser.withValue("Alice") {
51
println(getGreeting()) // "Hello, Alice!"
52
53
// Nested scoping
54
currentUser.withValue("Bob") {
55
println(getGreeting()) // "Hello, Bob!"
56
}
57
58
println(getGreeting()) // "Hello, Alice!" (restored)
59
}
60
61
println(getGreeting()) // "Hello, anonymous!" (original value)
62
63
// Logging context example
64
val logLevel = new DynamicVariable[String]("INFO")
65
66
def log(message: String): Unit = {
67
println(s"[${logLevel.value}] $message")
68
}
69
70
def processData(): Unit = {
71
log("Starting data processing")
72
73
logLevel.withValue("DEBUG") {
74
log("Detailed processing steps")
75
log("More debug information")
76
}
77
78
log("Data processing complete")
79
}
80
81
processData()
82
// Output:
83
// [INFO] Starting data processing
84
// [DEBUG] Detailed processing steps
85
// [DEBUG] More debug information
86
// [INFO] Data processing complete
87
88
// Database transaction context
89
val transactionId = new DynamicVariable[Option[String]](None)
90
91
def executeQuery(sql: String): Unit = {
92
val txId = transactionId.value.getOrElse("no-transaction")
93
println(s"[$txId] Executing: $sql")
94
}
95
96
def withTransaction[T](block: => T): T = {
97
val txId = java.util.UUID.randomUUID().toString.take(8)
98
transactionId.withValue(Some(txId)) {
99
println(s"[$txId] Starting transaction")
100
val result = block
101
println(s"[$txId] Committing transaction")
102
result
103
}
104
}
105
106
withTransaction {
107
executeQuery("SELECT * FROM users")
108
executeQuery("UPDATE users SET active = true")
109
}
110
```
111
112
### Enumeration Extended Features
113
114
Advanced enumeration functionality with custom values, ordering, and serialization support.
115
116
```scala { .api }
117
/**
118
* Extended enumeration with additional utility methods
119
*/
120
abstract class Enumeration {
121
/** Type alias for enumeration values */
122
type Value = EnumerationValue
123
124
/** Set containing all enumeration values */
125
def values: ValueSet
126
127
/** Get value by ID */
128
def apply(x: Int): Value
129
130
/** Try to get value by name */
131
def withName(s: String): Value
132
133
/** Iterator over all values */
134
def iterator: Iterator[Value]
135
136
/** Maximum ID used */
137
def maxId: Int
138
139
/** Next available ID */
140
protected var nextId: Int = 0
141
142
/** Create value with auto-assigned ID */
143
protected final def Value: Value = Value(nextId)
144
145
/** Create value with specific ID */
146
protected final def Value(i: Int): Value = Value(i, null)
147
148
/** Create value with name and auto-assigned ID */
149
protected final def Value(name: String): Value = Value(nextId, name)
150
151
/** Create value with specific ID and name */
152
protected final def Value(i: Int, name: String): Value
153
154
/**
155
* Individual enumeration value
156
*/
157
protected class Val(i: Int, name: String) extends EnumerationValue {
158
def id: Int = i
159
override def toString(): String = if (name != null) name else s"$$name"
160
}
161
162
/**
163
* Set of enumeration values with efficient operations
164
*/
165
class ValueSet extends Set[Value] {
166
def contains(elem: Value): Boolean
167
def +(elem: Value): ValueSet
168
def -(elem: Value): ValueSet
169
def iterator: Iterator[Value]
170
def size: Int
171
}
172
}
173
```
174
175
**Usage Examples:**
176
177
```scala
178
// HTTP Status enumeration
179
object HttpStatus extends Enumeration {
180
type HttpStatus = Value
181
182
val Ok = Value(200, "OK")
183
val Created = Value(201, "Created")
184
val BadRequest = Value(400, "Bad Request")
185
val NotFound = Value(404, "Not Found")
186
val InternalServerError = Value(500, "Internal Server Error")
187
}
188
189
// Using HTTP status
190
def handleResponse(status: HttpStatus.Value): String = status match {
191
case HttpStatus.Ok => "Request successful"
192
case HttpStatus.Created => "Resource created"
193
case HttpStatus.BadRequest => "Invalid request"
194
case HttpStatus.NotFound => "Resource not found"
195
case HttpStatus.InternalServerError => "Server error"
196
case _ => s"Unknown status: $status"
197
}
198
199
// Lookup by name and ID
200
val status1 = HttpStatus.withName("OK")
201
val status2 = HttpStatus(404)
202
203
println(s"Status: ${status1.id} - ${status1}")
204
println(s"Status: ${status2.id} - ${status2}")
205
206
// Iterate over all values
207
println("All HTTP statuses:")
208
for (status <- HttpStatus.values) {
209
println(s" ${status.id}: $status")
210
}
211
212
// Priority enumeration with ordering
213
object Priority extends Enumeration {
214
type Priority = Value
215
216
val Low = Value(1, "Low")
217
val Medium = Value(5, "Medium")
218
val High = Value(10, "High")
219
val Critical = Value(20, "Critical")
220
221
implicit val ordering: Ordering[Priority] = Ordering.by(_.id)
222
}
223
224
// Using priority with ordering
225
val tasks = List(
226
("Fix bug", Priority.High),
227
("Write docs", Priority.Low),
228
("Security patch", Priority.Critical),
229
("Refactor", Priority.Medium)
230
)
231
232
val sortedTasks = tasks.sortBy(_._2)
233
println("Tasks by priority:")
234
sortedTasks.foreach { case (task, priority) =>
235
println(s" [$priority] $task")
236
}
237
238
// State machine enumeration
239
object ConnectionState extends Enumeration {
240
type State = Value
241
242
val Disconnected, Connecting, Connected, Reconnecting, Failed = Value
243
244
def canTransitionTo(from: State, to: State): Boolean = (from, to) match {
245
case (Disconnected, Connecting) => true
246
case (Connecting, Connected | Failed) => true
247
case (Connected, Disconnected | Reconnecting) => true
248
case (Reconnecting, Connected | Failed) => true
249
case (Failed, Connecting) => true
250
case _ => false
251
}
252
}
253
254
// State transition validation
255
def changeState(current: ConnectionState.State, next: ConnectionState.State): Unit = {
256
if (ConnectionState.canTransitionTo(current, next)) {
257
println(s"State changed: $current -> $next")
258
} else {
259
println(s"Invalid transition: $current -> $next")
260
}
261
}
262
263
changeState(ConnectionState.Disconnected, ConnectionState.Connecting) // Valid
264
changeState(ConnectionState.Connected, ConnectionState.Failed) // Invalid
265
```
266
267
### Control Flow Utilities
268
269
Exception handling and control flow abstractions for robust error management.
270
271
```scala { .api }
272
/**
273
* Utility object for control flow operations
274
*/
275
object control {
276
/**
277
* Exception for non-local returns and control flow
278
*/
279
class ControlThrowable extends Throwable {
280
override def fillInStackTrace(): Throwable = this
281
}
282
283
/**
284
* Break exception for loop control
285
*/
286
class BreakControl extends ControlThrowable
287
288
/**
289
* Provides break functionality for loops
290
*/
291
object Breaks {
292
private val breakException = new BreakControl
293
294
/** Execute block with break support */
295
def breakable(op: => Unit): Unit = {
296
try {
297
op
298
} catch {
299
case _: BreakControl => // Expected break
300
}
301
}
302
303
/** Break out of enclosing breakable block */
304
def break(): Nothing = throw breakException
305
}
306
307
/**
308
* Exception handling utilities
309
*/
310
object Exception {
311
/** Catch exceptions and convert to Option */
312
def allCatch[T]: Catch[T] = new Catch[T](classOf[Throwable])
313
314
/** Catch specific exception types */
315
def catching[T](exceptions: Class[_]*): Catch[T] =
316
new Catch[T](exceptions: _*)
317
318
/** Ignore specific exceptions */
319
def ignoring(exceptions: Class[_]*): Catch[Unit] =
320
catching(exceptions: _*).opt.map(_ => ())
321
}
322
323
/**
324
* Exception catching utility
325
*/
326
class Catch[+T](exceptions: Class[_]*) {
327
/** Convert exceptions to Option */
328
def opt[U >: T](body: => U): Option[U] = {
329
try Some(body)
330
catch { case ex if exceptions.exists(_.isInstance(ex)) => None }
331
}
332
333
/** Provide default value on exception */
334
def either[U >: T](body: => U): Either[Throwable, U] = {
335
try Right(body)
336
catch { case ex if exceptions.exists(_.isInstance(ex)) => Left(ex) }
337
}
338
339
/** Apply recovery function on exception */
340
def recover[U >: T](pf: PartialFunction[Throwable, U])(body: => U): U = {
341
try body
342
catch {
343
case ex if exceptions.exists(_.isInstance(ex)) && pf.isDefinedAt(ex) => pf(ex)
344
}
345
}
346
}
347
}
348
```
349
350
**Usage Examples:**
351
352
```scala
353
import scala.util.control._
354
355
// Break support for loops
356
import Breaks._
357
358
def findFirstNegative(numbers: List[Int]): Option[Int] = {
359
var result: Option[Int] = None
360
361
breakable {
362
for (num <- numbers) {
363
if (num < 0) {
364
result = Some(num)
365
break() // Exit loop early
366
}
367
}
368
}
369
370
result
371
}
372
373
val numbers = List(1, 2, 3, -4, 5, -6)
374
println(findFirstNegative(numbers)) // Some(-4)
375
376
// Exception handling with allCatch
377
def parseNumber(s: String): Option[Int] = {
378
Exception.allCatch.opt(s.toInt)
379
}
380
381
println(parseNumber("123")) // Some(123)
382
println(parseNumber("invalid")) // None
383
384
// Specific exception catching
385
def safeDivide(a: Int, b: Int): Either[String, Int] = {
386
Exception.catching(classOf[ArithmeticException]).either(a / b) match {
387
case Left(ex) => Left(s"Division error: ${ex.getMessage}")
388
case Right(result) => Right(result)
389
}
390
}
391
392
println(safeDivide(10, 2)) // Right(5)
393
println(safeDivide(10, 0)) // Left("Division error: / by zero")
394
395
// Recovery with partial function
396
def robustOperation(input: String): String = {
397
Exception.allCatch.recover {
398
case _: NumberFormatException => "Invalid number format"
399
case _: NullPointerException => "Null input"
400
case ex => s"Unexpected error: ${ex.getMessage}"
401
} {
402
val number = input.toInt
403
(number * 2).toString
404
}
405
}
406
407
println(robustOperation("5")) // "10"
408
println(robustOperation("invalid")) // "Invalid number format"
409
println(robustOperation(null)) // "Null input"
410
411
// Ignoring specific exceptions
412
def attemptRiskyOperation(): Unit = {
413
Exception.ignoring(classOf[RuntimeException]) {
414
// This might throw RuntimeException, but we'll ignore it
415
if (scala.util.Random.nextBoolean()) {
416
throw new RuntimeException("Random failure")
417
}
418
println("Operation succeeded")
419
}
420
}
421
422
// Resource management pattern
423
def withResource[R <: { def close(): Unit }, T](resource: R)(block: R => T): T = {
424
try {
425
block(resource)
426
} finally {
427
Exception.ignoring(classOf[Exception]) {
428
resource.close()
429
}
430
}
431
}
432
433
// Usage with file-like resource
434
case class MockFile(name: String) {
435
def read(): String = s"Contents of $name"
436
def close(): Unit = println(s"Closed $name")
437
}
438
439
val result = withResource(MockFile("test.txt")) { file =>
440
file.read()
441
}
442
println(result) // "Contents of test.txt"
443
// Automatically prints: "Closed test.txt"
444
```