Block

Inherits from: Object

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).

Test
[3 + 4] value >>> 7
[:x | x * 2] value: 5 >>> 10
[:x :y | x + y] value: 3 value: 4 >>> 7
Example
"Blocks close over their environment"
| factor <Integer> |
factor := 10.
[:x | x * factor] value: 5

Instance Methods

primitives

forkRestricted:

Fork the block with restricted global access.

forkWith:

Fork the block with an argument, returns a Process.

forkWithContext:

Fork the block with a cancellation context.

primForkOn:
primForkOn:with:
primIfCurtailed:
primOn:do:
primSpawnOn:
primSpawnOn:with:
primValue
primValue:
primValue:value:
primValue:value:value:
whileFalse

Evaluate the receiver repeatedly while it returns false. Returns nil.

whileFalse:

Evaluate the receiver; while it returns false, evaluate block. Returns nil.

whileTrue

Evaluate the receiver repeatedly while it returns true. Returns nil.

whileTrue:

Evaluate the receiver; while it returns true, evaluate block. Returns nil.

uncategorized

ensure:

Evaluate the block, then unconditionally evaluate finallyBlock before returning. Returns the result of the receiver block.

Test
[1 + 2] ensure: [nil] >>> 3
[42] ensure: [99] >>> 42
fork

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.

Example
| proc <Process> |
proc := [self computeResult] fork.
proc wait
forkAt:

Fork the block at the given priority level. Returns the new Process.

Example
[self backgroundTask] forkAt: 1
forkOn:

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.).

Example
| node <Node> future <Future> |
node := Node connect: 'localhost:9200'.
future := [42 factorial] forkOn: node.
future await
forkOn:with:

Fork the block on a remote node with an argument. Returns a Future.

Example
| node <Node> future <Future> |
node := Node connect: 'localhost:9200'.
future := [:n | n factorial] forkOn: node with: 20.
future await
ifCurtailed:

Evaluate the block. If evaluation terminates abnormally (via exception or non-local return), evaluate curtailBlock for cleanup.

Example
[self doRiskyWork] ifCurtailed: [self cleanUp]
on:do:

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.

Example
[1 / 0] on: ZeroDivide do: [:e | 'caught']
repeat

Evaluate the block repeatedly, forever. The block must arrange its own exit (typically via a non-local return).

Example
| i <Integer> |
i := 0.
[i := i + 1. i > 10 ifTrue: [^i]] repeat
spawnOn:

Spawn a long-lived process on a remote node. Returns a RemoteProcess that can receive messages via cast:with: and asyncSend:with:.

Example
| node <Node> worker <RemoteProcess> |
node := Node connect: 'localhost:9200'.
worker := [Process receive payload println. self repeat] spawnOn: node.
worker cast: #hello: with: 'world'
spawnOn:with:

Spawn a long-lived process on a remote node with an initial argument. Returns a RemoteProcess.

Example
| node <Node> worker <RemoteProcess> |
node := Node connect: 'localhost:9200'.
worker := [:config | self runWith: config] spawnOn: node with: myConfig.
worker cast: #status: with: nil
value

Evaluate a zero-argument block and return its result.

Test
[42] value >>> 42
[3 + 4] value >>> 7
['hello'] value >>> 'hello'
value:

Evaluate a one-argument block, passing arg to its parameter.

Test
[:x | x * 2] value: 5 >>> 10
[:x | x + 1] value: 99 >>> 100
[:s | s, ' world'] value: 'hello' >>> 'hello world'
value:value:

Evaluate a two-argument block, passing arg1 and arg2 to its parameters.

Test
[:x :y | x + y] value: 3 value: 4 >>> 7
[:a :b | a * b] value: 6 value: 7 >>> 42
value:value:value:

Evaluate a three-argument block, passing arg1, arg2, and arg3.

Test
[:a :b :c | a + b + c] value: 1 value: 2 value: 3 >>> 6