README

#ref

This package provides functionality for working with mutable references, allowing you to create sharable mutable values that can be modified safely.

#Creating and Accessing References

References can be created using @ref.new(). The reference value can be accessed through the val field:

///|
test "creating and accessing refs" {
let r1 = @ref.new(42)
inspect(r1.val, content="42")
}

#Updating Reference Values

The update function allows modifying the contained value using a transformation function:

///|
test "updating refs" {
let counter = @ref.new(0)
counter.update(x => x + 1)
inspect(counter.val, content="1")
counter.update(x => x * 2)
inspect(counter.val, content="2")
}

#Mapping References

The map function transforms a reference while preserving the reference wrapper:

///|
test "mapping refs" {
let num = @ref.new(10)
let doubled = num.map(x => x * 2)
inspect(doubled.val, content="20")
let squared = num.map(x => x * x)
inspect(squared.val, content="100")
}

#Swapping Reference Values

You can exchange the values of two references using the swap function:

///|
test "swapping refs" {
let r1 = @ref.new("first")
let r2 = @ref.new("second")
@ref.swap(r1, r2)
inspect(r1.val, content="second")
inspect(r2.val, content="first")
}

#Temporary Value Protection

The protect function temporarily sets a reference to a value and restores it after executing a block:

///|
test "protected updates" {
let state = @ref.new(100)
let mut middle = 0
let result = state.protect(50, () => {
middle = state.val
42
})
inspect(middle, content="50")
inspect(result, content="42")
inspect(state.val, content="100")
}

This is useful for temporarily modifying state that needs to be restored afterwards.

#
Ref

pub(all) struct Ref[T] {
val : T
}

A simple mutable reference type that allows you to store and modify a value of any type.

test {
let x = @ref.Ref(42)
@test.assert_eq(x.val, 42)
x.val = 100
@test.assert_eq(x.val, 100)
}
impl Show for Ref[X]

#
Ref::Ref

#alias(new, deprecated="`new` is deprecated, use `Ref` instead")
fn[T] Ref::Ref(x : T) -> Ref[T]

create a reference from value

#
Ref::map

fn[T, R] Ref::map(self : Ref[T], f : (T) -> R raise?) -> Ref[R] raise?

Maps the value of a Ref using a given function.

Example

test {
@test.assert_eq(@ref.new(1).map(a => a + 1).val, 2)
}

#
Ref::protect

fn[T, R] Ref::protect(self : Ref[T], a : T, f : () -> R raise?) -> R raise?

This function allows you to temporarily replace the value of a reference with a new value, execute a given function, and then restore the original value of the reference.

Arguments

  • self: The reference whose value will be temporarily replaced.
  • a: The new value to assign to the reference.
  • f: The function to execute while the reference value is replaced.

Returns

The result of executing the provided function f.

Example

test {
let x = @ref.new(1)
x.protect(2, () => x.val = 3)
@test.assert_eq(x.val, 1)
}

#
Ref::swap

#as_free_fn
fn[T] Ref::swap(self : Ref[T], that : Ref[T]) -> Unit

Swaps the values of two references.

Example

test {
let x = @ref.new(1)
let y = @ref.new(2)
@ref.swap(x, y)
@test.assert_eq(x.val, 2)
@test.assert_eq(y.val, 1)
}

#
Ref::update

fn[T] Ref::update(self : Ref[T], f : (T) -> T raise?) -> Unit raise?

Applies f to the current value and stores the result.

#
new

fn[T] new(x : T) -> Ref[T]

Same as the Ref constructor.