命令是CachéObjectScript编程中的基本代码单元。CachéObjectScript中的所有执行任务都由命令执行。每个命令都包含一个命令关键字,后跟(在大多数情况下)一个或多个命令参数。
在CachéObjectScript中,所有命令语句都是显式的;CachéObjectScript代码的每个可执行行都必须以命令关键字开头。例如,要为变量赋值,必须指定set
关键字,后跟变量的参数和要赋值的值。
命令始终以关键字开头。考虑以下问题:
WRITE "Hello"
单词“write
”是命令关键字。它指定要执行的操作。write
命令的作用正如其名称所暗示的那样:它向主设备写入指定为其参数的任何内容。在本例中,Write
写入字符串“Hello”
。
CachéObjectScript命令名称不区分大小写。大多数命令名称都可以用缩写形式表示。因此,“WRITE”, “Write”, “write”, “W”, “w”
都是WRITE
命令的有效形式。
命令关键字不是保留字。因此,可以使用命令关键字作为用户为变量、标签或其他标识符指定的名称。
在CachéObjectScript程序中,代码行上的第一个命令必须缩进;COMMAND关键字不能出现在第1列中。从终端命令行提示符或从XECUTE
命令发出命令时,不需要缩进(允许缩进)。
可执行代码行可以包含一个或多个命令,每个命令都有自己的命令关键字。一行中的多个命令由一个或多个空格分隔。在同一行上,一个或多个命令可以跟在标签之后;标签和命令之间由一个或多个空格分隔。
在CachéObjectScript中,不需要或不允许使用命令结束分隔符或行尾分隔符。可以在命令后指定行内注释,指示命令行的其余部分为注释。除了##;
和/*COMMENT*/
语法之外,命令和注释语法的末尾之间需要空格。/*COMMENT*/
多行注释可以在命令中指定,也可以在命令的末尾指定。
在命令关键字之后,可以有零个、一个或多个参数来指定对象或命令范围。如果命令带有一个或多个参数,则命令关键字和第一个参数之间必须正好包含一个空格。例如:
SET x = 2
空格可以出现在参数内或参数之间,只要第一个参数的第一个字符与命令本身正好用一个空格隔开(如上所示)。因此,以下各项都是有效的:
SET a = 1
SET b=2
SET c=3,d=4
SET e= 5 , f =6
SET g
= 7
WRITE a,b,c,d,e,f,g
1234567
如果命令采用后置条件表达式,则命令关键字和后置条件之间不能有空格,并且后置条件和第一个参数的开头之间必须正好有一个空格。
QUIT x+y
QUIT x + y
QUIT:x<0
QUIT:x<0 x+y
QUIT:x<0 x + y
参数之间不需要空格,但参数之间可以使用多个空格。这些空格对命令的执行没有任何影响。但参数之间可以使用多个空格。还可以在命令参数内或命令参数之间包含换行符、制表符和注释,而不会影响命令的执行。
许多命令允许指定多个独立参数。命令参数的分隔符是逗号“,
”。也就是说,将单个命令的多个参数指定为该命令后面的逗号分隔列表。例如:
SET x=2,y=4,z=6
此命令使用三个参数为三个指定的变量赋值。在这种情况下,这些多个参数是重复的;也就是说,命令按照指定的顺序独立应用于每个参数。
在内部,Caché将其解析为三个单独的set命令。调试时,这些多个参数中的每个参数都是单独的步骤。
重复参数严格按照从左到右的顺序执行。因此,以下命令有效:
SET x=2,y=x+1,z=y+x
但是以下命令无效:
SET y=x+1,x=2,z=y+x
由于按照指定的顺序对每个重复参数独立执行执行,因此将执行有效参数,直到遇到第一个无效参数。在下面的示例中,set x
为x赋值,set y
生成
错误,并且由于不计算set z
,因此未检测到
(除以零)错误:
KILL x,y,z
SET x=2,y=z,z=5/0
WRITE "x is:",x
一些命令参数接受参数(不要与函数参数混淆)。如果给定的参数可以接受参数,则参数的分隔符是冒号“:
”)。
以下示例命令显示用作参数分隔符的逗号和用作参数分隔符的冒号。在本例中,有两个参数,每个参数有四个参数。
VIEW X:y:z:a,B:a:y:z
对于一些命令(DO
、XECUTE
和GOTO
),参数后面的冒号指定一个后置条件表达式,该表达式确定是否应该执行该参数。
不带参数的命令称为无参数命令。追加到关键字的后置条件表达式不被视为参数。
有一小部分命令始终是无参数的。例如,HALT
、CONTINUE
、TSTART
和TCOMMIT
是无参数命令。
有几个命令可以选择不带参数。例如,BREAK
、DO
、FOR
、GOTO
、KILL
和ZWRITE
都有无参数的语法形式。在这种情况下,无参数命令的含义可能与带参数的相同命令略有不同。
如果在行尾使用无参数命令,则不需要尾随空格。如果在与其他命令相同的代码行上使用无参数命令,则必须在无参数命令与其后面的任何命令之间放置两个(或更多)空格。例如:
QUIT:x=10 WRITE "not 10 yet"
在本例中,QUIT
是一个带有后置条件表达式的无参数命令,并且它和下一个命令之间至少需要两个空格。
当无参命令与由大括号分隔的命令块一起使用时,没有空格限制:
紧跟左大括号的无参数命令在命令名和大括号之间没有空格要求。可以不指定、指定一个或多个空格、制表符或换行符。对于可以接受参数的无参数命令(如FOR)和不能接受参数的无参数命令(如ELSE
)都是如此。
FOR {
WRITE !,"Quit out of 1st endless loop"
QUIT
}
FOR{
WRITE !,"Quit out of 2nd endless loop"
QUIT
}
FOR
{
WRITE !,"Quit out of 3rd endless loop"
QUIT
}
Quit out of 1st endless loop
Quit out of 2nd endless loop
Quit out of 3rd endless loop
```java
后面紧跟右大括号的无参数命令不需要尾随空格,因为右大括号充当分隔符。例如,以下是无参数的有效用法`QUIT`:
```java
IF 1=2 {
WRITE "Math error"}
ELSE {
WRITE "Arthmetic OK"
QUIT}
WRITE !,"Done"
Arthmetic OK
指定CachéObjectScript命令时,可以向其追加后置条件。
后置条件是附加到命令或(在某些情况下)控制Caché是否执行该命令或命令参数的命令参数的可选表达式。如果后置条件表达式的计算结果为TRUE(定义为非零),则Caché将执行命令或命令参数。决定Caché是否执行该命令或命令参数。果后置条件表达式的计算结果为FALSE(定义为零),则Caché不执行命令或命令参数,并从下一个命令或命令参数继续执行。
除了控制流命令(IF
、ELSEIF
和ELSE
;FOR
、WHILE
和DO WHILE
)和块结构错误处理命令(TRY
、THROW
、CATCH
)之外,所有CachéObjectScript命令都可以采用后置条件表达式。
CachéObjectScript命令DO
和XECUTE
可以将后置条件表达式附加到COMMAND关键字及其命令参数。后置条件表达式始终是可选的;例如,命令的某些参数可能有附加的后置条件,而其他参数则没有。
如果命令关键字和该命令一个或多个参数都指定了后置条件,则首先计算关键字PostConditional。只有当此关键字PostConditional的计算结果为true时,才会计算命令参数PostConditionals。如果命令关键字PostConditional的计算结果为FALSE,则不会执行该命令,程序将继续执行下一个命令。如果后置条件命令参数的计算结果为FALSE,则不会执行该参数,命令的执行将从左到右的顺序继续执行下一个参数。
要向命令添加后置条件,请在COMMAND关键字后面紧跟一个冒号(:
)和表达式,以便具有后置条件表达式的命令的语法为:
Command:pc
其中Command是命令关键字,冒号是必需的文字字符,PC可以是任何有效表达式。
后置条件命令必须遵循以下语法规则:
请注意,从技术上讲,后置条件表达式不是命令参数(尽管在ObjectScript参考页面中,后置条件的说明是作为参数部分的一部分提供的)。后置条件始终是可选的。
Caché将后置条件表达式计算为True或False。最常见的情况是用推荐值1和0表示这些值。但是,Caché对任何值执行后置条件求值,如果求值为0(零),则将其求值为false,如果求值为非零值,则求值为True。
True 1
, “1”
, 007
, 3.5
, -.007
, 7.0
, “3 little pigs”
, $CHAR(49)
,0_"1"
.false 0
, -0.0
, “A”
, “-”
, “$”
, “The 3 little pigs”
, $CHAR(0)
, $CHAR(48)
, "0_1"
.0=0
, 0="0"
, "a"=$CHAR(97)
, 0=$CHAR(48)
, (" "=$CHAR(32))
。以下求值结果为FALSE:0=""
, 0=$CHAR(0)
, (""=$CHAR(32))
。例如,以下写入命令的操作取决于变量COUNT
的值:
SET count = 4
WRITE:count<5 "count is less than 5.",!
SET count = 6
WRITE:count>5 "count is greater than 5.",!
count is less than 5.
count is greater than 5.
一行CachéObjectScript源代码可能包含多个命令及其参数。它们严格按照从左到右的顺序执行,并且在功能上与出现在单独行上的命令相同。源代码可以包含多个命令及其参数。带参数的命令必须与其后面的命令之间用一个空格字符分隔。无参数命令必须与其后面的命令之间用两个空格字符分隔。标签后可以在同一行上跟一个或多个命令。注释可以跟在同一行上的一个或多个命令之后。
为了提供必要的变量管理功能,ObjectScript提供了以下命令:
SET
为变量赋值。KILL
删除为变量赋值的操作。NEW
为变量赋值建立新的上下文。SET
set
命令为变量赋值。它可以为单个变量赋值,也可以同时为多个变量赋值。
Set
的最基本语法是:
SET variable = expression
这将设置单个变量的值。它还涉及几个步骤:
ObjectScript计算值表达式,确定其值(如果可能)。如果表达式包含未定义的变量、无效语法(例如除以零)或其他错误,则此步骤可能会生成错误。
如果该变量尚不存在,ObjectScript将创建它。
创建变量后,或者如果该变量已经存在,ObjectScript会将其值设置为表达式的值。
要设置多个变量中每个变量的值,请使用以下语法:
SET variable1 = expression1, variable2 = expression2, variable3 = expression3
要将多个变量设置为等于单个表达式,请使用以下语法:
SET (variable1,variable2,variable3)= expression
例如,若要设置Person类实例的Gender属性值,请使用以下代码:
SET person.Gender = "Female"
其中Person是对Person类的相关实例的对象引用。
还可以同时设置多个Person对象的性别属性:
SET (per1.Gender, per2.Gender, per3.Gender) = "Male"
其中,per1
, per2
, per3
是对Person
类的三个不同实例的对象引用。
可以使用Set
调用返回值的方法。调用方法时,Set
允许将变量、全局引用或属性设置为等于方法的返回值。参数的形式取决于方法是实例方法还是类方法。要调用类方法,请使用以下结构:
SET retval = ##class(PackageName.ClassName).ClassMethodName()
其中ClassMethodName()
是要调用的类方法的名称,ClassName
是包含方法的类的名称,PackageName
是包含类的包的名称。该方法的返回值被赋给retval
局部变量。##class()
构造是代码中必需的文字部分。
要调用实例方法,只需拥有本地实例化对象的句柄:
SET retval = InstanceName.InstanceMethodName()
其中,InstanceMethodName()
是要调用的实例方法的名称,而InstanceName
是包含该方法的实例的名称。该方法的返回值被赋给retval
局部变量。
KILL
kill
命令从内存中删除变量,并可用于从磁盘中删除它们。其基本形式是:
KILL expression
其中,表达式是要删除的一个或多个变量。那么,最简单的KILL
方式是:
KILL x
KILL x,y,z
一种称为“exclusive KILL”的特殊终止形式会删除除指定变量之外的所有局部变量。要使用“exclusive KILL,请将其参数放在括号中。例如,如果有变量x、y和z,则可以通过调用以下命令来删除y、z和除x之外的任何其他局部变量:
KILL (x)
如果没有任何参数,KILL将删除所有局部变量。
NEW
new命令创建一个新的局部变量上下文。这意味着它在旧上下文中保留现有的局部变量值,然后启动一个新的上下文,在新上下文中没有为局部变量赋值。在使用过程的应用程序中,使用NEW初始化整个应用程序或应用程序的主要子系统的变量。
支持以下语法形式:
NEW // 为所有局部变量启动新上下文
NEW x // 为指定的局部变量启动新上下文
NEW x,y,z // 为列出的局部变量启动新上下文
NEW (y) // 为除指定变量之外的所有局部变量启动新上下文
NEW (y,z) // 为除列出的变量之外的所有局部变量启动新上下文
以下命令用于支持命令组的执行:
Try/Catch
块结构:建议使用Try
和Catch
命令创建用于错误处理的块结构。对命令组的执行进行排序:TRY
块包含执行所需操作的多个命令。每个TRY
块都与一个CATCH
错误处理块配对,当TRY
块中发生错误时会调用该块。每个TRY
块后面必须紧跟其CATCH
块。如果需要,可以在程序中创建多个try/catch
块对。还可以嵌套try/catch
块对。可以从TRY
块中使用Throw
命令来显式调用相应的CATCH
块。TSTART
、TCOMMIT
和TROLLBACK
命令。建议在应该原子执行一组命令时(作为单个全有或全无代码单元),以TSTART
命令开始命令组,以TCOMMIT
命令结束命令组。如果在执行过程中出现问题,应该发出Troll back
命令来回滚命令组执行的操作。LOCK
命令。本节介绍用于调用执行一个或多个命令的命令:
DO
要在ObjectScript中调用例程、过程或方法,请使用do
命令。DO
的基本语法是:
DO ^CodeToInvoke
其中,CodeToInvoke可以是 Caché 系统例程或用户定义的例程。插入符号“^
”必须紧跟在例程名称之前。
可以通过引用例程中过程开始的行(也称为标记)的标签来运行例程中的过程。标签紧接在插入符号的前面。
例如:
SET %X = 484
DO INT^%SQROOT
WRITE %Y
22
此代码将%X
系统变量的值设置为484
;然后使用DO
调用Caché系统例程%SQROOT
的INT
过程,该过程计算值在%X
中的平方根并将其存储在%Y
中。然后,代码使用WRITE
命令显示%Y
的值。
调用方法时,DO
将指定方法的整个表达式作为单个参数。参数的形式取决于方法是实例方法还是类方法。要调用类方法,请使用以下结构:
DO ##class(PackageName.ClassName).ClassMethodName()
其中ClassMethodName()
是要调用的类方法的名称,ClassName
是包含方法的类的名称,PackageName
是包含类的包的名称。##class()
构造是代码中必需的文字部分。
要调用实例方法,只需拥有本地实例化对象的句柄:
DO InstanceName.InstanceMethodName()
其中,InstanceMethodName()
是要调用的实例方法的名称,而InstanceName
是包含该方法的实例的名称。
JOB
当DO
在前台运行代码时,JOB
在后台运行它。这独立于当前进程发生,通常无需用户交互。JOB
进程继承除明确指定的那些之外的所有系统默认值。
XECUTE
XECUTE
命令运行一个或多个CachéObjectScript命令;它通过计算作为参数接收的表达式(其参数必须计算为包含一个或多个CachéObjectScript命令的字符串)来执行此操作。实际上,每个XECUTE
参数就像一个由DO
命令调用的单行子例程,并在到达参数结尾或遇到QUIT
命令时终止。在Caché执行参数之后,它将控制返回到紧接XECUTE
参数之后的点。
QUIT
和 RETURN
QUIT
和RETURN
命令都终止代码块(包括方法)的执行。在没有参数的情况下,它们只需退出从中调用它们的代码。对于参数,它们将参数用作返回值。退出退出当前上下文,退出到封闭上下文。Return
将当前程序退出到程序被调用的位置。
下表显示了如何选择是否使用QUIT
RETURN
:
位置 | QUIT |
RETURN |
---|---|---|
例程代码(非块结构) | 退出例程,返回到调用例程(如果有)。 | 退出例程,返回到调用例程(如果有)。 |
Try 或Catch 块 |
将Try/Catch 块结构对退出到例程中的下一个代码。如果从嵌套的TRY 或CATCH 块发出,则从一级退出到封闭的TRY 或CATCH 块。 |
退出例程,返回到调用例程(如果有)。 |
DO 或XECUTE |
退出例程,返回到调用例程(如果有)。 | 退出例程,返回到调用例程(如果有)。 |
IF |
退出例程,返回到调用例程(如果有)。但是,如果嵌套在For 、While 或Do While 循环中,则退出块结构并继续代码块后下一行。 |
退出例程,返回到调用例程(如果有)。 |
FOR , WHILE, DO WHILE |
退出块结构并继续代码块之后的下一行。如果从嵌套块发出,则从一级退出到封闭块。 | 退出例程,返回到调用例程(如果有)。 |