Skip to content

Commit 0498dd0

Browse files
author
Enrico Granata
committed
Update the docs to reflect guard changes
Fix #4
1 parent 77c2da5 commit 0498dd0

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

manual.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -982,9 +982,11 @@ To help with defining a coherent set of comparison operators, the standard libra
982982

983983
## 👮 Guards
984984

985-
A guard statement is used to create a scoped block that can deallocate some managed resource on exit.
985+
A guard is used to create a scoped block that can deallocate some managed resource on exit. Note that a `guard`'s `do` block is not a lexical block, but it accepts a function (or really any callable object) that is invoked with the guarded object as argument. This means that the guarded object can outlive the `do` block if it is returned or stored somewhere else. It also means that the `do` block can capture variables from its caller scope, but these will be treated as captures, not as local variables.
986986

987987
```
988+
import guard from aria.utils.guard;
989+
988990
struct LoggedTask {
989991
type func new(op) {
990992
println("Starting {0}...".format(op));
@@ -999,20 +1001,26 @@ struct LoggedTask {
9991001
}
10001002
10011003
func main() {
1002-
guard op1 = LoggedTask.new("first task") { # prints Starting first task...
1004+
guard(LoggedTask.new("first task")).do(|x| => { # prints Starting first task...
10031005
# do the thing
1004-
} # prints first task completed
1006+
}); # prints first task completed
10051007
1006-
guard op2 = LoggedTask.new("second task") { # prints Starting second task...
1008+
guard(LoggedTask.new("second task")).do(|x| => { # prints Starting second task...
10071009
# do the thing
1008-
} # prints second task completed
1010+
}); # prints second task completed
10091011
}
10101012
```
10111013

10121014
In the general case, objects are deallocated transparently by the Aria VM, and there is no way to control the time and flow of the deallocation.
10131015

10141016
If an object needs to execute some custom cleanup, a `guard` block is the right way to assign additional behavior independent of the general VM deallocation. Note that an object can live outside of its guard block, and it's up to the object to respond safely to that.
10151017

1018+
`guard`s return a `Result` based on what their `do` block returns:
1019+
- if the block returns normally with a value, the guard returns `Result::Ok(value);
1020+
- if the block returns with a `Result::Ok(value)`, the guard returns `Result::Ok(value);
1021+
- if the block returns with a `Result::Err(err)`, the guard returns `Result::Err(err)`;
1022+
- if the block throws an exception, the guard re-throws it.
1023+
10161024
## 🥗 Mixins
10171025

10181026
Mixins can be used to insert new behavior into existing types. Aria does not provide inheritance, but some cases can instead be expressed via a `mixin`.

stdlib.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,33 @@ This module provides the core components for defining test cases and organizing
12131213
* `add_test(test)`: Adds a `TestCase` instance to the suite. Returns the `TestSuite` instance for chaining.
12141214
* `run(silent=false)`: Executes all test cases added to the suite. Prints the result of each test and a summary of passed/failed tests. Returns the number of failed tests. If `silent` is `true`, it suppresses the test runner's output during execution.
12151215

1216+
---
1217+
1218+
# `aria.utils` Module Reference
1219+
1220+
This document provides a reference for the `aria.utils` module, which contains utility functions and types for common programming tasks.
1221+
1222+
---
1223+
1224+
## Modules
1225+
1226+
### `aria.utils.guard`
1227+
1228+
This module provides the implementation for `guard`, a resource management utility.
1229+
1230+
#### **Functions**
1231+
1232+
* **`guard(obj)`**
1233+
Creates a new `GuardImpl` that wraps the provided object `obj`. The `obj` may optionally define a `guard_exit()` method, which will be called when the guard completes execution.
1234+
1235+
#### **Structs**
1236+
1237+
* **`GuardImpl`**
1238+
A wrapper for a managed resource that ensures a cleanup function is called when the guard completes execution.
1239+
1240+
**Methods:**
1241+
* `do(f)`: Runs `f` passing the guarded object as its sole argument. On completion, calls the cleanup function (`guard_exit`) on the guarded object, if one is provided. It returns a `Result` equivalent to `f(...)??`, or re-throws, if `f` throws.
1242+
12161243
---
12171244
# Built-in Values
12181245

0 commit comments

Comments
 (0)