文章目录

第四十七章 Caché 命令大全 DO (旧版) 命令

无参数:在同一程序中执行紧随其后的代码块。

重点
  1. 注意:此页面描述了传统的无参数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命令使用句点前缀将代码行组合在一起成为一个代码块。不使用花括号,并且行格式是限制性的。该语法已被花括号语法所取代。 IFFOR命令中不再需要无参数的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命令。如代码块语法中所指定,每个块命令行(包括注释和空白行)必须以一个或多个句点作为前缀。

示例

注意:请注意,以下示例使用IFFOR命令的旧版本。使用花括号(例如当前版本的IFFOR)来描绘代码块的命令不需要使用无参数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>

在以下示例中,无参数DO重复执行代码块,直到FOR控制变量(i)等于y的值。

/// 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后面的命令。