第七章 疯狂Caché 命令(一)

第七章 Caché 命令(一)

命令是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*/多行注释可以在命令中指定,也可以在命令的末尾指定。

扫描二维码关注公众号,回复: 11210219 查看本文章

命令参数

在命令关键字之后,可以有零个、一个或多个参数来指定对象或命令范围。如果命令带有一个或多个参数,则命令关键字和第一个参数之间必须正好包含一个空格。例如:

 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生成<UNDEFINED>错误,并且由于不计算set z,因此未检测到<DIVIDE>(除以零)错误:

   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

对于一些命令(DOXECUTEGOTO),参数后面的冒号指定一个后置条件表达式,该表达式确定是否应该执行该参数。

无参数命令

不带参数的命令称为无参数命令。追加到关键字的后置条件表达式不被视为参数。

有一小部分命令始终是无参数的。例如,HALTCONTINUETSTARTTCOMMIT是无参数命令。

有几个命令可以选择不带参数。例如,BREAKDOFORGOTOKILLZWRITE都有无参数的语法形式。在这种情况下,无参数命令的含义可能与带参数的相同命令略有不同。

如果在行尾使用无参数命令,则不需要尾随空格。如果在与其他命令相同的代码行上使用无参数命令,则必须在无参数命令与其后面的任何命令之间放置两个(或更多)空格。例如:

 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é不执行命令或命令参数,并从下一个命令或命令参数继续执行。

除了控制流命令(IFELSEIFELSEFORWHILEDO WHILE)和块结构错误处理命令(TRYTHROWCATCH)之外,所有CachéObjectScript命令都可以采用后置条件表达式。

CachéObjectScript命令DOXECUTE可以将后置条件表达式附加到COMMAND关键字及其命令参数。后置条件表达式始终是可选的;例如,命令的某些参数可能有附加的后置条件,而其他参数则没有。

如果命令关键字和该命令一个或多个参数都指定了后置条件,则首先计算关键字PostConditional。只有当此关键字PostConditional的计算结果为true时,才会计算命令参数PostConditionals。如果命令关键字PostConditional的计算结果为FALSE,则不会执行该命令,程序将继续执行下一个命令。如果后置条件命令参数的计算结果为FALSE,则不会执行该参数,命令的执行将从左到右的顺序继续执行下一个参数。

后置条件语法

要向命令添加后置条件,请在COMMAND关键字后面紧跟一个冒号()和表达式,以便具有后置条件表达式的命令的语法为:

Command:pc

其中Command是命令关键字,冒号是必需的文字字符,PC可以是任何有效表达式。

后置条件命令必须遵循以下语法规则:

  • 命令关键字与其后置条件之间或命令参数与其后置条件之间不允许有空格、制表符、换行符或注释。冒号字符前后不允许有空格。
  • 后置条件表达式中不允许有空格、制表符、换行符或注释,除非整个后置条件表达式包含在括号中,或者后置条件表达式具有括在括号中的参数列表。括号中允许使用空格、制表符、换行符和注释。
  • 后置条件表达式后面的间距要求与命令关键字后面的相同:关键字后置条件表达式的最后一个字符和第一个参数的第一个字符之间必须正好有一个空格;对于无参数命令,除非后置条件表达式后面紧跟右大括号,否则在同一行的后条件表达式的最后一个字符和下一个命令之间必须有两个或更多空格。(如果使用圆括号,则右括号将被视为后置条件表达式的最后一个字符。)

请注意,从技术上讲,后置条件表达式不是命令参数(尽管在ObjectScript参考页面中,后置条件的说明是作为参数部分的一部分提供的)。后置条件始终是可选的。

计算后置条件

Caché将后置条件表达式计算为True或False。最常见的情况是用推荐值1和0表示这些值。但是,Caché对任何值执行后置条件求值,如果求值为0(零),则将其求值为false,如果求值为非零值,则求值为True。

  • Caché将任何有效的非零数值计算为True。它对有效数值使用与算术运算符相同的标准。因此,以下全部求值为True 1, “1”, 007, 3.5, -.007, 7.0, “3 little pigs”, $CHAR(49),0_"1".
  • Caché将值零(0)和任何非数字值(包括空字符串(“”)或包含空格的字符串(“”))求值为false。以下全部求值为false 0, -0.0, “A”, “-”, “$”, “The 3 little pigs”, $CHAR(0), $CHAR(48), "0_1".
  • 适用标准的Caché 等价规则。因此,下面的求值结果为True: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块结构:建议使用TryCatch命令创建用于错误处理的块结构。对命令组的执行进行排序:TRY块包含执行所需操作的多个命令。每个TRY块都与一个CATCH错误处理块配对,当TRY块中发生错误时会调用该块。每个TRY块后面必须紧跟其CATCH块。如果需要,可以在程序中创建多个try/catch块对。还可以嵌套try/catch块对。可以从TRY块中使用Throw命令来显式调用相应的CATCH块。
  • 用于事务处理的TSTARTTCOMMITTROLLBACK命令。建议在应该原子执行一组命令时(作为单个全有或全无代码单元),以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é系统例程%SQROOTINT过程,该过程计算值在%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参数之后的点。

QUITRETURN

QUITRETURN命令都终止代码块(包括方法)的执行。在没有参数的情况下,它们只需退出从中调用它们的代码。对于参数,它们将参数用作返回值。退出退出当前上下文,退出到封闭上下文。Return将当前程序退出到程序被调用的位置。

下表显示了如何选择是否使用QUIT RETURN:

位置 QUIT RETURN
例程代码(非块结构) 退出例程,返回到调用例程(如果有)。 退出例程,返回到调用例程(如果有)。
TryCatch Try/Catch块结构对退出到例程中的下一个代码。如果从嵌套的TRYCATCH块发出,则从一级退出到封闭的TRYCATCH块。 退出例程,返回到调用例程(如果有)。
DOXECUTE 退出例程,返回到调用例程(如果有)。 退出例程,返回到调用例程(如果有)。
IF 退出例程,返回到调用例程(如果有)。但是,如果嵌套在ForWhileDo While循环中,则退出块结构并继续代码块后下一行。 退出例程,返回到调用例程(如果有)。
FOR, WHILE, DO WHILE 退出块结构并继续代码块之后的下一行。如果从嵌套块发出,则从一级退出到封闭块。 退出例程,返回到调用例程(如果有)。
原创文章 67 获赞 86 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yaoxin521123/article/details/106153991