Consulta y Observadores
En esta página
Verificar antes de disparar
.can_send("evento") devuelve true si el evento causaría una transición desde
el estado actual, sin modificar nada. Úsalo para habilitar o deshabilitar
botones de interfaz, validar entradas antes de confirmar, o escribir tests que
afirmen invariantes de protocolo.
Semáforo de dos estados: la respuesta de can_send se invierte conforme cambia el estado actual.
// Feature: `.can_send(event)` — check applicability without firing
// Syntax: returns true if the event would cause a transition from
// the current state, false otherwise.
// When to use: enable/disable UI buttons, validate input before
// committing, write tests that assert protocol invariants.
machine Light {
state Red, Green
initial Red
Red -> Green on go
Green -> Red on stop
}
let l = Light.new()
// In Red, "go" is valid but "stop" is not.
print(l.can_send("go")) // expected: true
print(l.can_send("stop")) // expected: false
l.send("go")
// In Green, the answer flips.
print(l.can_send("go")) // expected: false
print(l.can_send("stop")) // expected: true
Observar todas las transiciones
.on_transition(|from, to, event| { ... }) registra un observador que se dispara
después de cada transición exitosa — en orden de registro cuando hay varios. Es el
lugar adecuado para preocupaciones transversales: logs de auditoría, métricas, replay y
depuración, sin contaminar la definición de la máquina.
Contador A → B → C con un observador que imprime cada paso como from -> to via event.
// Feature: `.on_transition(callback)` — observe every transition
// Syntax: register a closure receiving `(from, to, event)`. Fires
// after each successful transition, in registration order.
// When to use: audit logs, metrics, replay/journaling, debugging
// — all the cross-cutting concerns that don't belong inside the
// machine definition.
machine Counter {
state A, B, C
initial A
A -> B on next
B -> C on next
C -> A on reset
}
let c = Counter.new()
c.on_transition(|from, to, event| {
print("{from} -> {to} via {event}")
})
c.send("next")
// expected: A -> B via next
c.send("next")
// expected: B -> C via next
c.send("reset")
// expected: C -> A via reset
Desafío
Registra dos observadores en el mismo contador: el primero imprime la transición, el
segundo acumula un conteo. Verifica que ambos se disparan en cada send.
Consulta también