Blocks are pieces of executable code which can be evaluated by sending
them a value-message (''value'', ''value:'', ''value:value:'' etc).
In smalltalk, Blocks provide the basic (and heavily used) mechanism
for looping, enumerating collection elements, visitors, exception
handling, unwinding, delayed execution and processes.
Blocks are never created explicitely; the only creation
is done by the compilers, when some sourceCode is compiled to either
machine or byteCode.
In the code, blocks are written as:
[
expression1.
...
expressionN
]
It represents the computation inside the brackets,
and can be passed around as argument, assigned to variables or returned from a block or method.
Creation of a block does NOT evaluate its expressions. You have to give the block to someone,
who asks it to evaluate itself. This is done by sending #value to the block.
i.e.
foo := [ Transcript showCR:'Hello World'].
...
foo value
Blocks are used in many many ways; one particular use is as callback:
|b|
b := Button label:'Press me'.
b action:[ Transcript showCR:'Hello'].
b open.
Blocks with arguments need a message of type ''value:arg1 ... value:argn''
for evaluation; the number of arguments passed when evaluating must match
the number of arguments the block was declared with otherwise an error is
raised.
Blocks without args need a ''value'' message for evaluation.
another use of blocks is in the enumeration protocols:
|coll|
coll := #( 'one' 'two' 'three').
coll do:[:eachElement | Transcript showCR:eachElement ].
Blocks keep a reference to the context where it was declared -
this allows blocks to access the method's arguments and/or variables.
This is still true after the method has returned - since the
block keeps this reference, the method's context will NOT die in this case.
(for experts: Smalltalk blocks are technically lambdas/closures)
A return (via ^-statement) out of a block will force a return from the
block's method context (if it is still living).
This is effectively a kind of long-jumps out of the method which declared the block
and makes control structures and loops possible.
If the method is not alive (i.e. has already returned), a return out of the
block will trigger an error.
Long-jump is done by defining a catchBlock as ''[^ self]''
somewhere up in the calling-tree. Then, to do the long-jump from out of some
deeply nested method, simply do: ''catchBlock value''.
[Instance variables:]
home <Context> the context where this block was created (i.e. defined)
this may be a blockContext or a methodContext
nargs <SmallInteger> the number of arguments the block expects
sourcePos <SmallInteger> the character position of its source, in chars
relative to methods source beginning
initialPC <SmallInteger> the start position within the byteCode
for compiled blocks, this is nil.
[Class variables:]
InvalidNewSignal raised if a Block is tried to be created
with new (which is not allowed).
Only the VM is allowed to create Blocks.
NOTICE: layout known by runtime system and compiler - do not change

VisualAge/ANSI compatibility:
evaluate the receiver and return its result.
After evaluation, also evaluate aBlock but ignore its result.aBlock is also evaluated in case of abnormal termination.
(the same as #valueNowOrOnUnwindDo:)

VisualAge/ANSI compatibility:
evaluate the receiver - when some method sent within unwinds (i.e. does
a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions (for example closing files etc.) are
executed regardless of error actions.
This is the same as #valueOnUnwindDo:

squeak compatibility:
Evaluate the receiver block and return its value, if no error occurs.
If an error is raised, return the value from handlerBlock.
The handlerBlock may take 0,1 or 2 args.
(1 arg -> the exception;
2 args -> the errorString and the erroneous receiver)

VisualAge compatibility: alias for #ensure:
evaluate the receiver - when the block returns either a local return
or an unwind (i.e. does a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions
(for example closing files etc.) are executed regardless of error actions.

VisualAge compatibility: alias for #ensure:
evaluate the receiver - when the block returns either a local return
or an unwind (i.e. does a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions
(for example closing files etc.) are executed regardless of error actions.

VisualAge compatibility: alias for #ensure:
evaluate the receiver - when the block returns either a local return
or an unwind (i.e. does a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions
(for example closing files etc.) are executed regardless of error actions.

VisualAge compatibility: alias for #ensure:
evaluate the receiver - when the block returns either a local return
or an unwind (i.e. does a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions
(for example closing files etc.) are executed regardless of error actions.

make myself a currying block;
that's a block which, if invoked with less-than-expected arguments,
returns another block which provides the provided argument(s) and expects the remaining args.
Read any book on functional programming, if you don't understand this.

(comment from inherited method)a helper for deepCopy; return a copy of the object with
all subobjects also copied. If the to-be-copied object is in the dictionary,
use the value found there. The class of the receiver is not copied.
This method DOES handle cycles/self references.

be aware that if you evaluate the following,
the blocks will be interpreted by the doIt.
Thus you will get on-realistic values.
Better compile those expressions into a method and call that
for realistic measurements.
[] benchmark:'empty block:' - this is a pre-compiled block
[123] benchmark:'empty block:' - the rest are interpreted blocks
[10 factorial] benchmark:'10 factorial:'
[10 factorial] benchmark:'11 factorial:'
[100 factorial] benchmark:'100 factorial:'

this error is triggered by the interpreter when a non-Block object
is about to be executed.
In this case, the VM sends this to the bad method (the receiver).
Can only happen when the Compiler/runtime system is broken or
someone played around.

evaluate the receiver with arguments as required taken from argArray.
Only the required number of arguments is taken from argArray or nil;
(i.e. argArray may be larger than the required number).
If the size of the argArray is smaller than the number of arguments, an error is raised.

evaluate the receiver with arguments as required taken from argArray.
If argArray provides less than the required number of arguments,
nil is assumed for any remaining argument.
(i.e. argArray may be smaller than the required number).
Only the required number of arguments is taken from argArray or nil;
(i.e. argArray may be larger than the required number).

added for ANSI compatibility; evaluate the receiver,
handling aSignalOrSignalSetOrException.
If the signal is raised during evaluation,
the 2nd argument, exceptionBlock is evaluated (and its value returned

added for ANSI compatibility; evaluate the receiver,
handling aSignalOrSignalSetOrException.
The 2nd argument, exceptionBlock is evaluated
if the signal is raised during evaluation.
The 3rd argument, ensureBlock is evaluated in any case - even if the activity
was unwound due to an unhandled exception.

evaluate the receiver,
handling aSignalOrSignalSetOrException.
The 2nd argument, exceptionBlock is evaluated
if the signal is raised during evaluation.
The 3rd argument, curtailBlock is evaluated if the activity
was unwound due to an unhandled exception in the receiver block
(but not in the exceptionBlock).

a watchdog on a block's execution. If the block does not finish its
evaluation after aTimeLimit milliseconds, it is interrupted (aborted) andexceptionBlock's value is returned. The receiver's code must be prepared
for premature returning (by adding ensure blocks, as required)

the receiver must be a block of one argument. It is evaluated in a loop forever,
and is passed a block, which, if sent a value:-message, will exit the receiver block,
returning the parameter of the value:-message. Used for loops with exit in the middle.
Inspired by a corresponding Self method.

the receiver must be a block of one argument. It is evaluated, and is passed a block,
which, if sent a value:-message, will exit the receiver block, returning the parameter of the
value:-message. Used for premature returns to the caller.
Taken from a manchester goody (a similar construct also appears in Self).

evaluate the receiver with interrupts blocked.
This does not prevent preemption by a higher priority processes
if any becomes runnable due to the evaluation of the receiver
(i.e. if a semaphore is signalled).

create a promise on the receiver. The promise will evaluate the
receiver and promise to return the value with the #value message.
The evaluation will be performed as a separate process.
Asking the promise for its value will either block the asking process
(if the evaluation has not yet been finished) or return the value
immediately.

create a promise on the receiver. The promise will evaluate the
receiver and promise to return the value with the #value message.
The evaluation will be performed as a separate process running at prio.
Asking the promise for its value will either block the asking process
(if the evaluation has not yet been finished) or return the value
immediately.

given a context which has been marked for unwind,
retrieve the handler block.
This avoids hardwiring access to the first argument in
#unwind methods (and theoretically allows for other unwinding
methods to be added)

evaluate the receiver, passing it one argument
- when some method sent within unwinds (i.e. does
a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions (for example closing files etc.) are
executed regardless of error actions

evaluate the receiver - after that, or when some method sent within unwinds (i.e. does
a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions (for example closing files etc.) are
executed regardless of error actions.
Same as the more modern, ANSI standardized #ensure:,
which should be used instead for portability.

evaluate the receiver - when some method sent within unwinds (i.e. does
a long return), evaluate the argument, aBlock.
This is used to make certain that cleanup actions (for example closing files etc.) are
executed regardless of error actions.
Same as the more modern, ANSI standardized #ifCurtailed:,
which should be used instead for portability.