You can include messages to objects in an expression wherever a term, such as a literal string, is valid. A message can be sent to an object to perform an action, obtain a result, or both.
A message term can have one of the following forms:
>>-receiver-+- ~ --+-messagename--+---------+------------------->
+- ~~ -+ +-:symbol-+
>--+--------------------------+--------------------------------><
+-(--+----------------+--)-+
| +-,----------+ |
| V | |
+---expression-+-+
>>-receiver[--+----------------+--]----------------------------><
| +-,----------+ |
| V | |
+---expression-+-+
The
receiver is a term (see
Section 1.11.1, “Terms and Expressions” for a definition of term). It receives the message. The ~ or ~~ indicates sending a message. The
messagename is a literal string or a symbol that is taken as a constant. The
expressions (separated by commas) between the parentheses or brackets are the arguments for the message. The
receiver and the argument
expressions can themselves include message terms. If the message has no arguments, you can omit the parentheses.
The left parenthesis, if present, must immediately follow a token (messagename or symbol) with no blank in between them. Otherwise, only the first part of the construct is recognized as a message term. (A blank operator would be assumed at that point.) Only a comment (which has no effect) can appear between a token and the left parenthesis.
You can use any number of expressions, separated by commas. The expressions are evaluated from left to right and form the arguments during the execution of the called method. Any ARG, PARSE ARG, or USE ARG instruction or ARG() built-in function in the called method accesses these objects while the called method is running. You can omit expressions, if appropriate, by including extra commas.
The
receiver object is evaluated, followed by one or more
expression arguments. The message name (in uppercase) and the resulting argument objects are then sent to the receiver object. The receiver object selects a method to be run based on the message name (see
Figure 4.1, “Classes and Inheritance (part 1 of 9)”), and runs the selected method with the specified argument objects. The receiver eventually returns, allowing processing to continue.
If the message term uses ~, the receiver method must return a result object. This object is included in the original expression as if the entire message term had been replaced by the name of a variable whose value is the returned object.
For example, the message POS is valid for strings, and you could code:
c="escape"
a="Position of 'e' is:" c~pos("e",3)
/* would set A to "Position of 'e' is: 6" */
If the message term uses ~~, the receiver method need not return a result object. Any result object is discarded, and the receiver object is included in the original expression in place of the message term.
For example, the messages INHERIT and SUBCLASS are valid for classes (see
Section 5.1.2, “The Class Class”) and, assuming the existence of the Persistent class, you could code:
account = .object~subclass("Account")~~inherit(.persistent)
/* would set ACCOUNT to the object returned by SUBCLASS, */
/* after sending that object the message INHERIT */
If the message term uses brackets, the message [] is sent to the receiver object. (The expressions within the brackets are available to the receiver object as arguments.) The effect is the same as for the corresponding ~ form of the message term. Thus, a[b]
is the same as a~"[]"(b)
.
Example 1.18. Arrays
a = .array~of(10,20)
say "Second item is" a[2] /* Same as: a~at(2) */
/* or a~"[]"(2) */
/* Produces: "Second item is 20" */
A message can have a variable number of arguments. You need to specify only those required. For example, "ESCAPE"~POS("E")
returns 1
.