DO (legacy version) (ObjectScript)
DO:pc . blockcommand . blockcommand nextcommand
|pc||Optional — A postconditional expression.|
|blockcommand||One or more ObjectScript commands executed as a code block. Note the presence of a period (.) prefix before each command in this block. Comments and blank lines must also have a period prefix.|
|nextcommand||The next ObjectScript command following the DO code block. This is the first line of code after the argumentless DO that is not prefixed by a period.|
This page describes the legacy argumentless DO command. The argumentless version of the DO command is considered legacy as of Caché 4.0, and should not be used in new programming. It is described here solely for compatibility with legacy applications.
The legacy argumentless DO command uses a period prefix to group lines of code together into a code block. Curly braces are not used and line formatting is restrictive. This syntax has been superseded by the curly brace syntax. Argumentless DO is no longer needed within IF or FOR commands, and the DO:pc operation has been superseded by the block-structured IF command. This syntax is not compatible with curly brace syntax; therefore, current Caché block structure commands such as IF and FOR that use curly brace syntax may not be used within an argumentless DO code block.
The argumentless DO command executes a block of code that immediately follows it in the same program. Argumentless DO blocks can be nested, and a postconditional expression on the DO command can be used to determine whether or not to execute a code block.
Caché executes the block of code that immediately follows the DO command, then executes the next command after that block of code.
The lines of code executed by an argumentless DO must be written using a special block structure syntax. This syntax uses periods (.) at the beginning of code lines. This block structure syntax is used only with the argumentless DO command.
You can specify the argumentless DO with a postconditional expression. If the postconditional expression tests FALSE (0), Caché skips the immediately following block of code (and any nested blocks of code within it) and continues execution at the same line level as the DO command.
Argumentless DO Block Structure
Because block structures immediately follow argumentless DO commands, you can use them to make your programs easier to read and maintain. As a rule, you should consider using block structures to replace short routines that are called only once and that might otherwise be spread throughout your code. The placement of block structures after their related DO commands makes it easier to find them. The obvious levels of the structures themselves make it easier to read the code.
A block structure consists of one or more blocks of code, with each block consisting of one or more lines on the same level of nesting. All of the lines on a given level are distinguished by having the same number of periods (.) as prefix to the line of code.
Code Block Syntax
Periods used to indicate the lines belonging to a code block take the following syntax:
The argumentless DO command should be the last command on its code line. It may be followed, after one or more whitespace characters, by a comment indicator character (; or //) on the same line.
The code line immediately following the argumentless DO command, and every line within the block of code must have a period prefix, even if it is a comment line or a blank line.
The periods must prefix the code line. Therefore, no commands or comments may appear before the periods or between the periods on a code line.
The period must be indented. That is, it cannot be in the first column of the code line. Usually, the initial period is indented to the same level as the code line containing the argumentless DO command.
Nested code blocks mark each level of nesting by using additional prefix periods. To indicate nesting, place the first period at the level of the code line containing the outermost DO, and indent with additional periods for each additional level of nesting.
A code block cannot contain labels. It can contain comment lines and blank lines, but these lines must be prefixed by a period, following the same rules as code lines.
A period must be followed by at least one whitespace character (a blank space or tab).
This space character must be followed by either a command keyword, another prefix period (.), a comment indicator (; or //), or a line return. Therefore, line breaks within a command should not be used with this syntax.
Period prefix code blocks should not be combined with code blocks delineated by curly braces.
Period prefix code blocks can be nested within each other. Because the lines belonging to a given code block all have the same number of prefix periods, you can easily visually distinguish the contents of each block.
When viewed in a listing, the lines in nested code blocks appear indented relative to each other. For example, the lines in an inner block contain one more prefix period character than the lines in the outer block that contains it.
When a block ends, as indicated by a line at with fewer prefix periods than the current line, ObjectScript issues an implicit QUIT that exits the block of code, and resumes execution at the previous level. You can code an explicit QUIT command as the last line of the block, but it is not necessary.
All code blocks share the same local variables. Therefore, you can supply a value to an inner block by setting a variable before invoking that code block level. Similarly, any results from the execution of an inner block can be preserved at the next higher level by changing the values of shared local variables.
The $TEST special variable is handled differently by argumentless DO, than by a DO command calling a subroutine or procedure. The argumentless DO preserves the initial value of $TEST during execution of its code block. If the block includes a command (such as a legacy IF command, or a timed OPEN) that resets the value of $TEST, this change is not passed back to the next higher level.
If you issue a QUIT command within an argumentless DO code block, Caché quits the immediate code block and continues execution with the next command following that code block.
The following example shows this QUIT behavior:
DO . WRITE "into the DO",! . DO .. WRITE "inner DO",! .. QUIT .. WRITE "never written",! . WRITE "back to outer DO",! . QUIT . WRITE "never written",! WRITE "out of the DO"
An optional postconditional expression. Caché executes the command if the postconditional expression is true (evaluates to a nonzero numeric value). Caché does not execute the command if the postconditional expression is false (evaluates to zero). For further details, refer to Command Postconditional Expressions in Using Caché ObjectScript.
One or more ObjectScript commands executed as a code block. Each blockcommand line (including comments and blank lines) must be prefixed by one or more periods, as specified in the Code Block Syntax.
Note that the following examples use the legacy versions of the IF and FOR commands. Commands that delineate a block of code using curly braces (such as the current version of IF and FOR) do not need to use the argumentless DO, and are not compatible with period prefix syntax.
In the following example, the two argumentless DO commands each invoke a block of code. Which DO is executed and, consequently, which block is invoked depends on which operation the user requests, as determined by the IF command. In each case, the result is passed back to the WRITE command through the same shared local variable. The first block (which calculates the square of an integer) contains an implicit QUIT while the second block (which calculates the cube of an integer) contains an explicit QUIT.
Start ; Square or cube an integer. READ !,"Square (S) or cube (C): ",op QUIT:op="" READ !,"Integer: ",num QUIT:num="" IF (op["S")!(op["s") DO . SET result=num*num ; Square block . WRITE !,"Result: ",result ELSE DO . SET result=num*num*num ; Cube block . WRITE !,"Result: ",result . QUIT GOTO Start
In the following example, the argumentless DO repeatedly executes the code block until the FOR control variable (i) equals the value of y.
FOR i=1:1:y DO . SET z=z*x . WRITE !,z . QUIT
The following example shows nested code blocks in ObjectScript, using implicit QUIT commands to end each block.
MyRoutine ; Routine label WRITE !,"At top level" ; Mainline code (Level count = 0) DO . ; Outermost block (Level count = 1) . . DO . . ; Inner block 1 (Level count = 2) . . . . DO . . . ; Inner block 2 (Level count = 3) . . . . . ; (Level count = 2) . ; (Level count = 1) . . QUIT ; (Level count = 0) WRITE !,"Back at top level" ; Mainline code resumes
As shown in the preceding example, the first argumentless DO begins execution of the lines in the outermost block of code. ObjectScript saves the line level at which the DO resides. If ObjectScript encounters subsequent argumentless DO commands, it executes the next inner block of code and increments the line level by one for each such command. When it finds an implicit or explicit QUIT in a block, ObjectScript decrements the line level count by one and continues execution at the command that follows the DO for that block.