Block
A closure capturing its enclosing scope. Blocks are the fundamental unit of deferred evaluation: control flow, iteration, exception handling, and concurrency are all built on block evaluation.
Blocks are created with square-bracket syntax and evaluated with value,
value:, value:value:, or value:value:value: depending on how many
arguments the block expects. Zero-argument blocks are also used by the
primitive loop forms whileTrue:, whileFalse:, whileTrue, and
whileFalse (implemented as VM primitives, not Maggie methods).
[3 + 4] value >>> 7
[:x | x * 2] value: 5 >>> 10
[:x :y | x + y] value: 3 value: 4 >>> 7
"Blocks close over their environment"
| factor <Integer> |
factor := 10.
[:x | x * factor] value: 5
Instance Methods
primitives
Fork the block with restricted global access.
Fork the block with an argument, returns a Process.
Fork the block with a cancellation context.
Evaluate the receiver repeatedly while it returns false. Returns nil.
Evaluate the receiver; while it returns false, evaluate block. Returns nil.
Evaluate the receiver repeatedly while it returns true. Returns nil.
Evaluate the receiver; while it returns true, evaluate block. Returns nil.
uncategorized
Evaluate the block, then unconditionally evaluate finallyBlock before returning. Returns the result of the receiver block.
[1 + 2] ensure: [nil] >>> 3
[42] ensure: [99] >>> 42
Fork the block as a lightweight Process (goroutine). Returns the new Process immediately; the block runs concurrently. Non-local returns (^) inside the forked block are treated as local returns and will not escape the process boundary.
| proc <Process> |
proc := [self computeResult] fork.
proc wait
Fork the block at the given priority level. Returns the new Process.
[self backgroundTask] forkAt: 1
Fork the block on a remote node. Returns a Future that resolves when the block completes on the remote node. The block's captured variables must be serializable (no Channels, Processes, Mutexes, etc.).
| node <Node> future <Future> |
node := Node connect: 'localhost:9200'.
future := [42 factorial] forkOn: node.
future await
Fork the block on a remote node with an argument. Returns a Future.
| node <Node> future <Future> |
node := Node connect: 'localhost:9200'.
future := [:n | n factorial] forkOn: node with: 20.
future await
Evaluate the block. If evaluation terminates abnormally (via exception or non-local return), evaluate curtailBlock for cleanup.
[self doRiskyWork] ifCurtailed: [self cleanUp]
Evaluate the block inside an exception handler. If an exception matching the given exception class is signaled during evaluation, the handler block is invoked with the exception object.
[1 / 0] on: ZeroDivide do: [:e | 'caught']
Evaluate the block repeatedly, forever. The block must arrange its own exit (typically via a non-local return).
| i <Integer> |
i := 0.
[i := i + 1. i > 10 ifTrue: [^i]] repeat
Spawn a long-lived process on a remote node. Returns a RemoteProcess
that can receive messages via cast:with: and asyncSend:with:.
| node <Node> worker <RemoteProcess> |
node := Node connect: 'localhost:9200'.
worker := [Process receive payload println. self repeat] spawnOn: node.
worker cast: #hello: with: 'world'
Spawn a long-lived process on a remote node with an initial argument. Returns a RemoteProcess.
| node <Node> worker <RemoteProcess> |
node := Node connect: 'localhost:9200'.
worker := [:config | self runWith: config] spawnOn: node with: myConfig.
worker cast: #status: with: nil
Evaluate a zero-argument block and return its result.
[42] value >>> 42
[3 + 4] value >>> 7
['hello'] value >>> 'hello'
Evaluate a one-argument block, passing arg to its parameter.
[:x | x * 2] value: 5 >>> 10
[:x | x + 1] value: 99 >>> 100
[:s | s, ' world'] value: 'hello' >>> 'hello world'
Evaluate a two-argument block, passing arg1 and arg2 to its parameters.
[:x :y | x + y] value: 3 value: 4 >>> 7
[:a :b | a * b] value: 6 value: 7 >>> 42
Evaluate a three-argument block, passing arg1, arg2, and arg3.
[:a :b :c | a + b + c] value: 1 value: 2 value: 3 >>> 6