When a method or block is executed, a Call object is created, which can be accessed from within the method's body. This object can be used for a number of things, like introspection, evaluating arguments on demand, etc.
/* more here... */
By using call evalArgAt(n), it is possible to evaluate the argument at position n.
Io methods don't need to "declare" all their arguments in the argument list. In fact, they can take an arbitrary number of arguments, which can be retrieved and evaluated at will from inside the method body. For example, consider this implementation of times, a method that executes some code n times, and returns a list with the results.
times := method(n,
result := list()
n repeat(
value := call evalArgAt(1)
result append(value)
)
return result
)
x := times(5, Random value)
x println
(Argument 0 is evaluated automagically and bound to n, but argument 1 is evaluated on demand. In this case, it's evaluated several times.)
[Note: It would have been perfectly possible to make times a method of Number...]
call sendercall message arguments to get the arguments (if any) passed to the non-existent message; these arguments are unevaluated at this pointcall message argsEvaluatedIn(call sender) to get the arguments (if any) passed to the non-existent message, evaluated in the context of the sender