Transition Actions
Each transition can carry an action block written in braces right after the
event name: A -> B on event { ... }. The block executes synchronously after the
transition is decided, but before .send returns — ideal for side effects that
are cohesive with the state change (logs, hardware pulses, animation triggers).
Door with four transitions, each printing a message when fired.
02-actions.zolo
// Feature: transition actions — code that runs on transition
// Syntax: `A -> B on event { <body> }`. The block runs after the
// transition is decided but before `.send` returns.
// When to use: side effects tied to state changes — log lines,
// hardware pulses, animation triggers, audio events.
machine Door {
state Closed, Open, Locked
initial Closed
Closed -> Open on open { print("door opened") }
Open -> Closed on close { print("door closed") }
Closed -> Locked on lock { print("door locked") }
Locked -> Closed on unlock { print("door unlocked") }
}
let door = Door.new()
print(door.state) // expected: Closed
door.send("open") // expected: door opened
print(door.state) // expected: Open
door.send("close") // expected: door closed
print(door.state) // expected: Closed
door.send("lock") // expected: door locked
print(door.state) // expected: Locked
door.send("unlock") // expected: door unlocked
print(door.state) // expected: Closed
Keep the blocks small. For heavier work, prefer spawning a coroutine with spawn
inside the action instead of blocking send.
See also