Saltar al contenido

25 · Máquinas de Estado

Consulta y Observadores

`.can_send` verifica si un evento es aplicable; `.on_transition` registra observadores globales.

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.

03-can-send.zolo
Playground
// 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.

04-on-transition.zolo
Playground
// 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

Índice global

Encuentra tu camino por Zolo

Prueba una idea

Empieza aquí

9 resultados

9 resultados

enespt-br