class Atom[T <: Shareable]

A shared cell holding an immutable value, which any task can read and replace atomically. The replacement for shared mutable state: an update computes a new value from the old one and swaps it in.

hits = Atom.new(0)
Task.scope { |s| 3.times { s.spawn { hits.update { |n| n + 1 } } } }
hits.value       # => 3

<prelude>:6069

Class methods

def self.new(value: T) -> Atom[T]

A new atom holding value.

<prelude>:6073

Methods

def value -> T

The value held now.

<prelude>:6075

def get -> T

The value held now (as #value).

<prelude>:6077

def set(value: T) -> Void

Replaces the value with value.

<prelude>:6079

def update(&: (T) -> T) -> T

Replaces the value with the block's result for the current value, and returns the new value.

When another task changes the value meanwhile, the block runs again with the newer one: keep it free of side effects.

a = Atom.new({"a" => 1})
a.update { |h| h.put("b", 2) }   # => {"a" => 1, "b" => 2}

<prelude>:6090

def compare_and_set(expected: T, replacement: T) -> Bool

Replaces the value with replacement if it is still expected: whether it did. Compared by identity, as Java's AtomicReference compares: expected is the value read (get), not one equal to it made apart (numbers, strings, symbols, Bytes and Time compare by their contents).

a = Atom.new([1, 2])
old = a.get
a.compare_and_set(old, [3])      # => true
# An equal array made apart is not the one held.
a.compare_and_set([3], [4])      # => false
a.compare_and_set(a.get, [4])    # => true

<prelude>:6105