Context & Variables
Context variables ($) represent data owned by a machine instance. They persist across events and can be manipulated with natural language operations.
Basic Concepts
Every machine instance has its own context - isolated data that belongs only to that instance:
machine: @order
scenario: cart management
on> :add_item from @customer
$items adds $item // This order's items
$total increases by $price // This order's totalDifferent order instances have their own $items and $total - they don't share data.
Setting Values
Basic Assignment
$total becomes 100
$name becomes "John Doe"
$is_active becomes true
$items becomes emptyWith Type Annotations
Type annotations are optional but help with documentation and validation:
$total: number becomes 100
$name: string becomes "John Doe"
$is_active: boolean becomes true
$items: array becomes empty
$config: object becomes emptySupported Types
| Type | Description | Example |
|---|---|---|
string | Text values | "Hello" |
number | Integers and decimals | 100, 99.99 |
boolean | True/false | true, false |
array | List of items | ["a", "b"] |
object | Key-value pairs | {key: value} |
Arithmetic Operations
Increase
$total increases by 25
$count increases by 1
$balance increases by $depositDecrease
$total decreases by 10
$stock decreases by $quantity
$attempts decreases by 1Examples
on> :add_item from @customer
$total increases by $item.price
$item_count increases by 1
on> :apply_discount from @customer
$total decreases by $discount_amount
on> :remove_item from @customer
$total decreases by $item.price
$item_count decreases by 1Collection Operations
Add to Collection
$items adds "Laptop"
$items adds $new_item
$tags adds "urgent"Remove from Collection
$items removes "Laptop"
$items removes $item
$tags removes "completed"Clear Collection
$items clears
$tags clears
$history clearsComplete Example
machine: @shopping_cart
scenario: cart operations
on> :add_to_cart from @customer
$items: array adds $product
$total: number increases by $product.price
on> :remove_from_cart from @customer
$items removes $product
$total decreases by $product.price
on> :clear_cart from @customer
$items clears
$total becomes 0Reading Context in Guards
Use context variables in conditions:
? $total is greater than 100
apply free shipping
? $item_count equals 0
show empty cart message
? $items contains "Gift Card"
apply gift card discount
? $user_type is "premium"
apply premium discountComparison Patterns
| Pattern | Meaning |
|---|---|
$var equals value | Equal to |
$var is value | Equal to |
$var is not value | Not equal to |
$var is greater than value | > |
$var is less than value | < |
$var is at least value | >= |
$var is at most value | <= |
$var contains value | Array/string contains |
$var is empty | Empty collection/string |
$var is not empty | Non-empty |
Context in Assertions
Verify context values in expect: blocks:
scenario: checkout
given:
$total: number is 0
on> :add_item from @customer
$total increases by $item.price
expect:
= $total equals 1200
= $items contains "Laptop"
= $item_count equals 1Context in Given Blocks
Initialize context for testing:
scenario: apply discount
given:
$total: number is 1200
$discount_code: string is "SUMMER20"
$items: array contains "Laptop"
on> :apply_discount from @customer
? $discount_code is valid
$total decreases by 100
expect:
= $total equals 1100Accessing Nested Data
Access properties of complex objects:
$total increases by $item.price
$customer_name becomes $order.customer.name
? $payment.status is "completed"
order moves to #paidContext Scope
Instance Scope
Each machine instance has its own context:
@order:abc123 → $total: 1200, $items: ["Laptop"]
@order:xyz789 → $total: 50, $items: ["Mouse"]Event Data Access
Event data is available during event handling:
on> :checkout from @customer
// $order_id comes from the event payload
$internal_order_id becomes $order_id
$customer_email becomes $customer.emailBuilt-in Values
Some values are provided by the runtime:
$created_at becomes now // Current timestamp
$updated_at becomes now
$id becomes generated_id // System-generated IDNo Binding Required
Simple context operations work without PHP binding:
// These work automatically
$total becomes 100
$total increases by 25
$items adds "Laptop"
$items clearsComplex operations that require business logic can be bound to PHP when needed.
Best Practices
Use Descriptive Names
// Good
$order_total: number becomes 0
$cart_items: array becomes empty
$customer_email: string becomes ""
// Avoid
$t becomes 0
$arr becomes empty
$e becomes ""Initialize in Given Blocks
scenario: checkout
given:
$total: number is 0
$items: array is empty
$discount_applied: boolean is falseUse Type Annotations for Clarity
// Clear intent
$retry_count: number becomes 0
$is_premium: boolean becomes false
$tags: array becomes empty