第四十七章 Caché 命令大全 DO (旧版) 命令
无参数:在同一程序中执行紧随其后的代码块。
重点
- 注意:此页面描述了传统的无参数
DO
命令。从Caché4.0开始,DO
命令的无参数版本被认为是旧版本,不应在新的编程中使用。此处仅出于与旧版应用程序兼容的目的对其进行描述。
大纲
DO:pc
. blockcommand
. blockcommand
nextcommand
参数
- pc 可选-后置条件表达式。
- blockcommand 作为代码块执行的一个或多个CachéObjectScript命令。请注意,此块中每个命令之前都有一个句点(
。
)前缀。注释和空白行还必须带有句点前缀。 - nextcommand DO代码块之后的下一个CachéObjectScript命令。这是无参
DO
后面没有句号前缀的第一行代码。
描述
注意:此页面描述了传统的无参数DO
命令。从Caché4.0开始,DO
命令的无参数版本被认为是旧版本,不应在新的编程中使用。此处仅出于与旧版应用程序兼容的目的对其进行描述。
传统的无参数DO
命令使用句点前缀将代码行组合在一起成为一个代码块。不使用花括号,并且行格式是限制性的。该语法已被花括号语法所取代。 IF
或FOR
命令中不再需要无参数的DO
,而DO:pc
操作已被块结构的IF
命令取代。该语法与花括号语法不兼容;因此,使用无花括号的语法的当前Caché块结构命令(例如IF和FOR)可能不会在无参数的DO
代码块中使用。
无参数的DO
命令在同一程序中执行紧随其后的代码块。可以嵌套无参数的DO
块,并且可以使用DO命令上的后置条件表达式来确定是否执行代码块。
Caché执行紧随DO
命令之后的代码块,然后执行该代码块之后的下一个命令。
无参数DO
执行的代码行必须使用特殊的块结构语法编写。此语法在代码行的开头使用句点(。
)。此块结构语法仅与无参数DO
命令一起使用。
可以使用后置条件表达式指定无参数的DO
。如果后置条件表达式测试为FALSE(0),则Caché跳过紧随其后的代码块(以及其中的任何嵌套代码块),并在与DO
命令相同的行级别继续执行。
无参数DO块结构
由于块结构立即跟随无参数DO
命令,因此可以使用它们使程序更易于阅读和维护。通常,应该考虑使用块结构来替换仅被调用一次的短例程,否则该短例程可能会散布在整个代码中。将块结构放置在相关的DO
命令之后,可以更轻松地找到它们。结构本身的明显层次使其更易于阅读代码。
块结构由一个或多个代码块组成,每个块由同一嵌套级别上的一行或多行组成。给定级别上的所有行都通过与代码行的前缀具有相同数量的句点(。
)来区分。
代码块语法
用于指示属于代码块的行的句点采用以下语法:
- 无参数的
DO
命令应该是其代码行上的最后一个命令。在一个或多个空格字符之后,可以在同一行后跟一个注释指示符(;
或//
)。 - 紧跟无参数
DO
命令的代码行,并且代码块中的每一行都必须带有句点前缀,即使它是注释行或空白行也是如此。 - 句点必须在代码行之前。因此,在代码行上的句点之前或句点之间可能没有命令或注释出现。
- 该期间必须缩进。也就是说,它不能在代码行的第一列中。通常,初始期间缩进到与包含无参数
DO
命令的代码行相同的级别。 - 嵌套的代码块通过使用其他前缀周期来标记嵌套的每个级别。为了表示嵌套,请将第一个句点放在包含最外面的
DO
的代码行的级别上,并为每个附加嵌套级别缩进附加句点。 - 代码块不能包含标签。它可以包含注释行和空白行,但是这些行必须以句点作为前缀,并遵循与代码行相同的规则。
- 句点后面必须至少有一个空格字符(空格或制表符)。
- 该空格字符后必须跟命令关键字,另一个前缀句点(
。
),注释指示符(;
或//
)或换行符。因此,命令内的换行符不应与此语法一起使用。 - 句点前缀代码块不应与用花括号描绘的代码块组合。
嵌套
句点前缀代码块可以相互嵌套。由于属于给定代码块的行均具有相同数量的前缀周期,因此可以轻松地从视觉上区分每个块的内容。
在清单中查看时,嵌套代码块中的行相对于彼此出现缩进。例如,内部块中的行比包含它的外部块中的行多包含一个前缀周期字符。
当一个块结束时,如前缀行比当前行少的一行所示,CachéObjectScript发出一个隐式QUIT
退出代码块,并在上一级继续执行。您可以将显式QUIT
命令编码为该块的最后一行,但这不是必需的。
变量
所有代码块共享相同的局部变量。因此,可以在调用该代码块级别之前通过设置变量来向内部块提供值。同样,通过更改共享局部变量的值,内部块执行的任何结果都可以保留在更高的级别。
$TEST
特殊变量通过无参数DO
处理的方式与通过调用子例程或过程的DO
命令的处理方式不同。无参数DO
在其代码块执行期间保留$TEST
的初始值。如果该块包含重置$TEST
值的命令(例如旧版IF
命令或定时OPEN
),则此更改不会传递回下一个更高的级别。
QUIT命令
如果在无参数的DO
代码块中发出QUIT
命令,则Caché退出立即代码块,并继续执行该代码块之后的下一个命令。下面的示例显示此QUIT行为:
/// d ##class(PHA.TEST.Command).TestLegDo()
ClassMethod TestLegDo(str)
{
DO
. WRITE "进入DO",!
. DO
.. WRITE "内部DO",!
.. QUIT
.. WRITE "永远不会written",!
. WRITE "回到外部 DO",!
. QUIT
. WRITE "永远不会written",!
WRITE "退出 DO"
}
参数
pc
可选的后置条件表达式。如果后置条件表达式为true(计算为非零数值),则Caché执行命令。如果后置条件表达式为假(计算为零),则Caché不执行命令。
blockcommand
作为代码块执行的一个或多个CachéObjectScript命令。如代码块语法中所指定,每个块命令行(包括注释和空白行)必须以一个或多个句点作为前缀。
示例
注意:请注意,以下示例使用IF
和FOR
命令的旧版本。使用花括号(例如当前版本的IF
和FOR
)来描绘代码块的命令不需要使用无参数DO
,并且与句点前缀语法不兼容。
在下面的示例中,两个无参数的DO
命令每个都调用一个代码块。执行哪个DO
,然后调用哪个块取决于IF
命令确定的用户请求的操作。在每种情况下,结果都通过相同的共享局部变量传递回WRITE
命令。第一个块(用于计算整数的平方)包含一个隐式QUIT
,而第二个块(用于计算整数的立方)包含一个显式QUIT
。
/// d ##class(PHA.TEST.Command).TestLegDo1()
ClassMethod TestLegDo1(str)
{
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
}
DHC-APP>d ##class(PHA.TEST.Command).TestLegDo1()
Square (S) or cube (C): C
Integer: 1
Result: 1
Square (S) or cube (C): S
Integer: 5
Result: 25
Square (S) or cube (C): C
Integer: 5
Result: 125
Square (S) or cube (C):
DHC-APP>
```java
在以下示例中,无参数`DO`重复执行代码块,直到`FOR`控制变量(i)等于`y`的值。
```java
/// d ##class(PHA.TEST.Command).TestLegDo2()
ClassMethod TestLegDo2(str)
{
s y = 5,z = 2,x = 3
FOR i=1:1:y DO
. SET z=z*x
. WRITE !,z
. QUIT
}
DHC-APP>d ##class(PHA.TEST.Command).TestLegDo2()
6
18
54
162
486
以下示例显示了CachéObjectScript中的嵌套代码块,使用隐式QUIT
命令结束每个块。
/// d ##class(PHA.TEST.Command).TestMyRoutine()
ClassMethod TestMyRoutine(str)
{
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
}
DHC-APP> d ##class(PHA.TEST.Command).TestMyRoutine()
At top level
Back at top level
如前面的示例所示,第一个无参数的DO
开始执行最外层代码块中的行。 CachéObjectScript保存DO所在的行级别。如果CachéObjectScript遇到后续的无参数DO
命令,它将执行下一个内部代码块,并为每个此类命令将行级别增加一。当它在一个块中找到一个隐式或显式QUIT
时,CachéObjectScript会将行级别计数减一,并继续执行该块DO
后面的命令。