ObjectScript的某些部分区分大小写,而其他部分不区分大小写。一般来说,ObjectScript的用户可定义部分区分大小写,而关键字不区分大小写:
#include
)、字母代码(用于LOCK
、OPEN
或USE
)、关键字代码(用于$STACK
)、模式匹配代码和嵌入式代码指令(&html
、&js
和&sql
)。通过自定义%ZLANG例程
添加的自定义语言元素不区分大小写;创建它们时必须使用大写,引用它们时可以使用任何大小写。由于iKnow索引通过将文本转换为小写来标准化文本,因此大多数iKnow值(包括域名)都不区分大小写。%SYSTEM.Process
的ScienceNotation()
方法将小写“e”配置为当前进程的有效或无效,也可以使用Config.Miscellous类的ScienceNotation属性在系统范围内将其配置为有效或无效。注意:相比之下,CachéSQL标识符不区分大小写。
Unicode字符是16位字符,也称为宽字符。如果在Caché安装过程中选择了Unicode选项,则你的Caché实例支持Unicode国际字符集。如果在Caché安装期间选择了8位选项,则不支持 C H A R ( 255 ) 以 外 的 字 符 ; CHAR(255)以外的字符; CHAR(255)以外的字符;CHAR函数返回大于255的整数的空字符串。$ZVERSION
特殊变量和$SYSTEM.Version.IsUnicode()
方法显示Caché安装是否支持Unicode。
在Caché的Unicode安装上,某些名称可以包含Unicode字母字符,而其他名称不能包含Unicode字母。Unicode字母定义为ASCII值大于255的字母字符。例如,希腊文的小写lambda是$Char(955)
,这是一个Unicode字母。
整个Caché允许使用Unicode字母字符,以下例外情况除外:
注意:日语区域设置不支持缓存名称中带重音的拉丁字母字符。除日文字符外,日文名称还可以包含拉丁字母字符A-Z和a-z(65-90和97-122),以及希腊大写字母字符(913-929和931-937)。
在某些情况下,ObjectScript将空格视为语法上有意义的。除非另有说明,否则空白指的是空格、制表符和换行符。简而言之,规则是:
CachéStudio提供内置的语法检查,因此它将标记任何非法使用的空格,例如在命令的第一个参数之前插入多个空格,语法检查如下图所示:
使用注释在代码中提供内联文档是一种很好的做法,因为在修改或维护代码时,注释是很有价值的资源。CachéObjectScript支持几种类型的注释。
在int代码中,有几种类型的注释可用,所有注释都必须在第2列或更大列中开始:
注意:因为Caché在目标代码(实际解释和执行的代码)中保留了;;注释,所以包含它们会影响性能,并且它们不应该出现在循环中。
多行注释(/*注释*/
)可以放在命令或函数参数之间,可以放在逗号分隔符之前或之后。多行注释不能放在参数内,也不能放在命令关键字与其第一个参数或函数关键字与其左括号之间。它可以放在同一行的两个命令之间,在这种情况下,它起到分隔命令所需的单个空格的作用。可以紧跟在多行注释(*/)的末尾,在同一行上使用命令,也可以在它之后在同一行上添加单行注释。
以下示例显示了/*注释*/
在一行中的以下插入:
/// d ##class(PHA.TEST.ObjectScript).TestComments()
ClassMethod TestComments()
{
WRITE $PIECE("Fred&Ginger"/* WRITE "world" */,"&",2),!
WRITE "hello",/* WRITE "world" */" sailor",!
SET x="Fred"/* WRITE "world" */WRITE x,!
WRITE "hello"/* WRITE "world" */// WRITE " sailor"
}"
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestComments()
Ginger
hello sailor
Fred
hello
所有对int代码有效的注释类型也都对MAC代码有效,并且在MAC代码中的行为与它们在int代码中的行为相同。另外两种注释类型也可用:
#DEFINE
、#Def1Arg
或##CONTINUE
宏预处理器指令在同一行中使用。在类定义内,但在方法定义之外,有几种注释类型可用,所有这些类型都可以从任何列开始:
文字是由一系列表示特定字符串或数值的字符组成的常量值,例如下面的“Hello”和“5”:
SET x = "Hello"
SET y = 5
字符串文字是由引号分隔的一组零个或多个字符(与字符串文字不同,数字文字不需要分隔符)。CachéObjectScript字符串文字用双引号分隔(例如,“myliteral”);cachéSQL字符串文字用单引号分隔(例如,‘mycripal’)。这些引号分隔符不计入字符串长度。
字符串可以包含任何字符,包括空格和控制字符。字符串文字的长度以字符串中的字符数而不是字节数来度量。字符串只能包含8位ASCII字符。在Unicode系统上,字符串还可以包含16位Unicode字符(称为宽字符)。如果字符串中包含单个宽字符,则Caché会将字符串中的所有字符表示为16位字符。因为caché几乎总是将字符串视为字符,而不是字节,所以这种宽字符的使用通常对用户是不可见的。(ZZDUMP命令是一个例外,如下所示。)
最大字符串大小是可配置的。如果启用了长字符串,则最大字符串大小为3,641,144个字符。否则,最大字符串大小为32,767个字符。默认情况下启用长字符串。
下面的Unicode示例显示了一个8位字符的字符串、一个16位字符(希腊字母)的字符串和一个组合字符串:
/// d ##class(PHA.TEST.ObjectScript).TestUnicode()
ClassMethod TestUnicode()
{
DO AsciiLetters
IF $SYSTEM.Version.IsUnicode() {
DO GreekUnicodeLetters
DO CombinedAsciiUnicode
RETURN }
ELSE { WRITE "Unicode not supported"
RETURN }
AsciiLetters()
SET a="abc"
WRITE a
WRITE !,"the length of string a is ",$LENGTH(a)
ZZDUMP a
GreekUnicodeLetters()
SET b=$CHAR(945)_$CHAR(946)_$CHAR(947)
WRITE !!,b
WRITE !,"the length of string b is ",$LENGTH(b)
ZZDUMP b
CombinedAsciiUnicode()
SET c=a_b
WRITE !!,c
WRITE !,"the length of string c is ",$LENGTH(c)
ZZDUMP c
}
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestUnicode()
abc
the length of string a is 3
0000: 61 62 63 abc
αβγ
the length of string b is 3
0000: 03B1 03B2 03B3 αβγ
abcαβγ
the length of string c is 6
0000: 0061 0062 0063 03B1 03B2 03B3 abcαβγ
不是所有字符串都可以输入的。您可以使用$CHAR函数指定不可输入的字符,如下面的Unicode示例所示:
SET greekstr=$CHAR(952,945,955,945,963,963,945)
WRITE greekstr
θαλασσα
并非所有字符串字符都可显示。它们可以是非打印字符或控制字符。WRITE命令将非打印字符表示为方框符号。WRITE命令导致执行控制字符。在以下示例中,字符串包含的可打印字符与NULL( C H A R ( 0 ) ) 、 T a b 键 ( CHAR(0))、Tab键( CHAR(0))、Tab键(CHAR(9))和回车($CHAR(13))字符交替:
SET a="a"_$CHAR(0)_"b"_$CHAR(9)_"c"_$CHAR(13)_"d"
WRITE !,"the length of string a is ",$LENGTH(a)
ZZDUMP a
WRITE !,a
the length of string a is 7
0000: 61 00 62 09 63 0D 64 a.b.c.d
ab c
d
请注意,WRITE命令执行来自终端命令行的一些控制字符,这些字符在程序中的写入执行显示为非打印字符。例如,Bell( C H A R ( 7 ) ) 和 V e r t i c a l T a b 垂 直 制 表 符 ( CHAR(7))和Vertical Tab 垂直制表符( CHAR(7))和VerticalTab垂直制表符(CHAR(11))字符。
要在字符串中包含引号字符(“),请将字符加倍,如下例所示:
SET x="This quote"
SET y="This "" quote"
WRITE x,!," string length=",$LENGTH(x)
ZZDUMP x
WRITE !!,y,!," string length=",$LENGTH(y)
ZZDUMP y
This quote
string length=10
0000: 54 68 69 73 20 71 75 6F 74 65 This quote
This " quote
string length=12
0000: 54 68 69 73 20 22 20 71 75 6F 74 65 This " quote
不包含任何值的字符串称为空字符串。它由两个引号字符("")表示。空字符串被视为已定义的值。它的长度为0。请注意,空字符串与由空字符($CHAR(0))组成的字符串不同,如下例所示:
SET x=""
WRITE "string=",x," length=",$LENGTH(x)," defined=",$DATA(x)
ZZDUMP x
SET y=$CHAR(0)
WRITE !!,"string=",y," length=",$LENGTH(y)," defined=",$DATA(y)
ZZDUMP y
string= length=0 defined=1
string= length=1 defined=1
0000: 00 .
数字文字是ObjectScript计算为数字的值。它们不需要分隔符。Caché将数字文字转换为规范形式(其最简单的数字形式):
SET x = ++0007.00
WRITE "length: ",$LENGTH(x),!
WRITE "value: ",x,!
WRITE "equality: ",x = 7,!
WRITE "arithmetic: ",x + 1
length: 1
value: 7
equality: 1
arithmetic: 8
还可以将数字表示为用引号分隔的字符串文字;数字字符串文字不会转换为规范形式,但可以在算术运算中用作数字:
SET y = "++0007.00"
WRITE "length: ",$LENGTH(y),!
WRITE "value: ",y,!
WRITE "equality: ",y = 7,!
WRITE "arithmetic: ",y + 1
length: 9
value: ++0007.00
equality: 0
arithmetic: 8
ObjectScript将包含以下内容(且不包含其他字符)的任何值视为数字:
值 | 数量 |
---|---|
数字0-9 | 任何数量,但至少有一个。 |
符号运算符:一元减号(-)和一元加号(+)。 | 任何数量,但必须在所有其他字符之前。 |
小数分隔符字符(默认情况下为句点或小数点字符;在欧洲区域设置中为逗号字符)。 | 最多一个。 |
字母“E”(用于科学记数法)。 | 最多一个。必须出现在两个数字之间。 |
ObjectScript可以使用以下类型的数字:
标识符是变量、例程或标签的名称。通常,合法标识符由字母和数字字符组成;除少数例外情况外,标识符中不允许使用标点符号。标识符区分大小写。
与标识符命名约定相比,用户定义的命令、函数和特殊变量的命名约定具有更多限制(仅允许使用字母)。
本文档的变量一章提供了局部变量、进程私有全局变量和全局变量的命名约定。
某些标识符可以包含一个或多个标点符号。这些包括:
标识符的第一个字符可以是百分号(%)字符。以%字符开头的Caché名称(以%Z或%z开头的Caché存名称除外)保留为系统元素。
全局或进程专用全局名称(但不是局部变量名称)可以包括一个或多个(.)。字符。例程名称可以包括一个或多个(.)。字符。“.”不能是标识符的第一个或最后一个字符。
请注意,全局变量和进程专用全局变量由一个或多个字符的插入符号(^)前缀标识,如下所示:
这些前缀字符不是变量名的一部分;它们标识存储的类型以及(在全局情况下)用于此存储的命名空间。实际名称开始于最后一个竖线或右方括号之后。
任何一行ObjectScript代码都可以选择性地包括标签(label)(也称为标签(tag))。标签用作在代码中引用该行位置的句柄。标签是未缩进的标识符;它在第1列中指定。所有cachéObjectScript命令都必须缩进。
标签具有以下命名约定:
第一个字符必须是字母数字字符或百分比字符(%)。请注意,标签是唯一可以以数字开头的cachéObjectScript名称。第二个字符和所有后续字符必须是字母数字字符。标签可以包含Unicode字母。
它们最长可达31个字符。标签可以长于31个字符,但在前31个字符内必须是唯一的。标签引用仅与标签的前31个字符匹配。但是,标签或标签引用的所有字符(不仅仅是前31个字符)都必须遵守标签字符命名约定。
区分大小写。
注:在SQL命令(如CREATE PROCEDURE或CREATE TRIGGER)中指定的ObjectScript代码块可以包含标签。在本例中,标签的第一个字符的前缀是在第1列中指定的冒号(:)。标签的其余部分遵循此处描述的命名和使用要求。
标签可以包括或省略参数括号。如果包含,这些圆括号可以是空的,也可以包括一个或多个逗号分隔的参数名称。带括号的标签标识过程块。
一行只能由标签、后面跟着一个或多个命令的标签或后面跟着注释的标签组成。如果命令或注释在同一行的标签之后,则必须用空格或制表符将它们与标签隔开。
以下都是唯一的标签:
/// d ##class(PHA.TEST.ObjectScript).TestLabel()
ClassMethod TestLabel()
{
maximum
Max
MAX
86
agent86
86agent
%control
}
可以使用$ZNAME函数来验证标签名称。验证标签名称时,请不要使用参数括号。
可以使用ZINSERT命令将标签名称插入到源代码中。
标签对于标识代码段和管理控制流很有用。
DO和GOTO命令可以将它们的目标位置指定为标签。$ZTRAP特殊变量可以将其错误处理程序的位置指定为标签。JOB命令可以将要执行的例程指定为标签。
PRINT、ZPRINT、ZZPRINT、ZINSERT、ZREMOVE和ZBREAK命令以及$TEXT函数也使用标签来标识源代码行。
但是,不能在与CATCH命令相同的代码行上指定标签,也不能在TRY块和CATCH块之间指定标签。
标签提供入口点,但它没有定义封装的代码单元。这意味着一旦标记的代码执行,执行将继续到下一个标记的代码单元,除非执行被停止或重定向到其他地方。
有三种方法可以停止执行代码单元:
在下面的示例中,代码执行从“label0”下的代码继续到“label1”下的代码:
/// d ##class(PHA.TEST.ObjectScript).TestUseLabel()
ClassMethod TestUseLabel()
{
SET x = $RANDOM(2)
IF x=0 {DO label0
WRITE "Finished Routine0",!
QUIT }
ELSE {DO label1
WRITE "Finished Routine1",!
QUIT }
label0
WRITE "In Routine0",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1 }
WRITE "At the end of Routine0",!
label1
WRITE "In Routine1",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1 }
WRITE "At the end of Routine1",!
}
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestUseLabel()
In Routine0
x = 0
x = 1
x = 2
x = 3
x = 4
At the end of Routine0
In Routine1
x = 5
x = 6
x = 7
x = 8
x = 9
At the end of Routine1
Finished Routine0
在下面的示例中,标记的代码段以Quit或Return命令结尾。这会导致执行停止。请注意,Return始终停止执行,Quit停止当前上下文的执行:
/// d ##class(PHA.TEST.ObjectScript).TestRetQuitCom()
ClassMethod TestRetQuitCom()
{
SET x = $RANDOM(2)
IF x=0 {DO label0
WRITE "Finished Routine0",!
QUIT }
ELSE {DO label1
WRITE "Finished Routine1",!
QUIT }
label0
WRITE "In Routine0",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1
QUIT }
WRITE "Quit the FOR loop, not the routine",!
WRITE "At the end of Routine0",!
QUIT
WRITE "This should never print"
label1
WRITE "In Routine1",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1 }
WRITE "At the end of Routine1",!
RETURN
WRITE "This should never print"
}
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestRetQuitCom()
In Routine0
x = 0
Quit the FOR loop, not the routine
At the end of Routine0
Finished Routine0
DHC-APP>d ##class(PHA.TEST.ObjectScript).TestRetQuitCom()
In Routine1
x = 1
x = 2
x = 3
x = 4
x = 5
At the end of Routine1
Finished Routine1
在下面的示例中,第二个和第三个标签标识程序块(使用参数括号指定的标签)。遇到过程块标签时停止执行:
SET x = $RANDOM(2)
IF x=0 {DO label0
WRITE "Finished Routine0",!
QUIT }
ELSE {DO label1
WRITE "Finished Routine1",!
QUIT }
label0
WRITE "In Routine0",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1 }
WRITE "At the end of Routine0",!
label1()
WRITE "In Routine1",!
FOR i=1:1:5 {
WRITE "x = ",x,!
SET x = x+1 }
WRITE "At the end of Routine1",!
label2()
WRITE "This should never print"
In Routine1
x = 1
x = 2
x = 3
x = 4
x = 5
At the end of Routine1
Finished Routine1
名字空间名称可以是显式的名字空间名称或隐含的名字空间名称。显式命名空间名称不区分大小写;不管输入时使用的字母大小写,它始终以大写字母存储和返回。
在显式命名空间名称中,第一个字符必须是字母或百分号(%)。其余字符必须是字母、数字、连字符(-)或下划线(_)。名称不能超过255个字符。
当Caché 将显式名称空间名称转换为例程或类名时(例如,在创建Caché 的查询类/例程名称时),它会将标点符号字符替换为小写字母,如下所示:%=p,_=u,-=d。隐含的名称空间名称可以包含其他标点符号;在翻译隐含的名称空间名称时,这些标点符号将被小写的"s"替换。因此,以下七个标点符号被替换为:@=s、:=s、/=s、=s、[=s、]=s、^=s。
保留以下命名空间名称:%SYS、BIN、Broker、DOCBOOK和DOCUMATIC。
使用cachéSQL create database命令时,创建SQL数据库会创建相应的caché名称空间。
使用 Caché MultiValue时,创建一个MultiValue帐户将创建相应的Caché名称空间。多值帐户和隐藏命名空间的命名约定不同。
扩展引用是对位于另一个命名空间中的实体的引用。命名空间名称可以指定为引号括起的字符串文字、解析为命名空间名称的变量、隐含的命名空间名称或指定当前命名空间的占位符的空字符串 ("")。
有三种类型的扩展引用:
扩展全局引用:引用另一个命名空间中的全局变量。支持以下语法形式: ^ ["namespace"]global
和 ^|"namespace"|global
.
扩展例程引用:引用另一个命名空间中的例程。
do命令、$TEXT函数和用户定义函数支持以下语法形式:|"namespace"|例程
。
JOB命令支持以下语法形式:例程|"namespace"|
、例程|"namespace"|
或例程:“命名空间”。
在所有这些情况下,扩展例程引用的前缀都是^(上剪头字符),表示指定的实体是例程(而不是标签或偏移量)。此插入符号不是例程名称的一部分。例如, ^ |"SAMPLES"|fibonacci
调用名为Fibonacci的例程
,该例程位于Samples命名空间中。命令write$$FUN ^ |“Samples”|house
调用位于Samples名称空间中的例程房屋中的用户定义函数Fun()。
/// d ##class(PHA.TEST.ObjectScript).TestAcrossProcess()
ClassMethod TestAcrossProcess()
{
WRITE $$test^|"DHC-LISDATA"|PHATest
}
^$["namespace"]ssvn
和 ^$|"namespace"|ssvn
.当然,所有扩展引用都可以通过名称显式指定当前名称空间,也可以通过指定空字符串占位符来指定。
CachéObjectScript中没有保留字;可以使用任何有效的标识符作为变量名、函数名或标签。同时,最好避免使用命令名、函数名或其他此类字符串的标识符。此外,由于ObjectScript代码包括对嵌入式SQL的支持,因此谨慎的做法是避免使用SQL保留字命名任何函数、对象、变量或其他实体,因为这可能会在其他地方造成困难。