Saltar al contenido

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.

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

Buscar en Zolo

9 resultados

enespt-br