文章目录
第四十三章 Caché 命令大全 ZLOAD 命令 - 重点
- 大纲
-
- 参数
- 描述
-
- 不带参数的ZLOAD
- 从设备加载例程
- 从终端创建例程
- `ZLOAD`带参数
- 参数
-
- pc
- routine
- 注意
-
- Namespaces
- ZLOAD的常规行为
- ^rINDEX例行时间戳记和大小
- INT代码和^ ROUTINE全局变量
- ZLOAD和语言模式
- 示例
将例程加载到当前例程缓冲区中。
重点- 终端输入ZLOAD命令。
ZLOAD:pc routine ZL:pc routine
参数
- pc 可选-后置条件表达式。
- routine 可选-要加载的例程,以简单文字形式指定。例程值不包含在引号中。它没有尖号(^)前缀或文件类型后缀。不能使用变量或表达式指定。如果省略,则Caché从当前设备加载未命名的例程。
ZLOAD命令将ObjectScript例程的INT代码版本作为当前例程加载。 ZLOAD有两种形式:
- 有参
- 无参
从终端输入ZLOAD命令或使用XECUTE命令或$XECUTE函数调用ZLOAD命令时,只能使用ZLOAD命令。不应将其编码到例程的主体中,因为其操作会影响该例程的执行。在例程中指定ZLOAD会导致编译错误。从例程中执行ZLOAD的任何尝试也会产生错误。
一旦使用ZLOAD将例程作为当前例程加载,就可以使用DO命令执行当前例程,使用ZINSERT和自变量ZREMOVE编辑当前例程,使用ZPRINT显示例程行,保存(并选择重命名)已编辑的当前例程。使用ZSAVE,最后使用无参数的ZREMOVE卸载当前例程。
不带参数的ZLOAD
不带参数的ZLOAD命令将未命名的ObjectScript例程作为当前进程的当前例程加载到例程缓冲区中。随后,可以使用ZSAVE例程来命名该例程。请注意,由于该例程未命名,因此不能使用$ZNAME特殊变量来确定是否加载了当前例程。
无参数ZLOAD可以通过两种方式使用:
- 从顺序文件或其他设备加载例程。
- 使用终端创建例程。
无参数的ZLOAD命令可以指定后置条件表达式。
从设备加载例程
要从设备加载例程,请执行以下操作:
- 发出OPEN命令以打开设备。
- 发出USE命令以使设备成为当前设备。
- 发出无参数ZLOAD命令以从设备中加载例程作为当前例程。
行加载将继续,直到Caché读取空字符串行(“”)。直到使用ZSAVE例程命令将其加载之前,此加载的例程才有名称。
从终端创建例程
可以使用无参数的ZLOAD创建未命名的例程,作为终端程序中的当前例程:
- 在终端提示下,发出无参数ZLOAD命令。
- 在下面的行中,键入例程的第一个ObjectScript命令(不带引号),然后按Enter键两次。通常,此行是标签名称或标签名称,后跟可执行的ObjectScript代码。可执行的ObjectScript代码必须缩进。
- 在终端提示下,发出ZINSERT命令以向当前例程添加更多行。
- (可选)在终端提示下,发出ZSAVE例程以指定名称保存该例程。
- 完成后,使用无参数ZREMOVE卸载当前例程。
或者,可以使用ZINSERT创建一个未命名的例程作为终端中的当前例程。
ZLOAD带参数
ZLOAD例程将现有ObjectScript例程的INT代码版本从当前名称空间加载到例程缓冲区中,作为当前进程的当前例程。 INT代码不计算或不包含预处理程序语句。
ZLOAD在加载例程时会执行隐式无参数ZREMOVE。也就是说,ZLOAD删除任何先前加载的例程,将其替换为指定的例程。可以使用$ZNAME特殊变量来确定当前加载的例程。 ZLOAD加载例程时,它将行指针定位在例程的开头。
一旦加载,例程将一直是该过程的当前例程,直到使用ZLOAD命令显式加载另一个例程,使用无参数的ZREMOVE将其删除,或者使用DO或GOTO命令隐式加载另一个例程。
只要例程是最新的,就可以编辑例程(使用ZINSERT和ZREMOVE命令),使用ZPRINT命令显示一行或多行,或者使用$TEXT函数返回一行。
参数pc
可选的后置条件表达式。如果后置条件表达式为true(计算为非零数值),则Caché执行命令。如果后置条件表达式为假(计算为零),则Caché不执行命令。
routine
当前名称空间中现有ObjectScript例程的名称,该名称将作为当前例程加载。例程名称区分大小写。
必须具有例程的执行许可权,才能对其进行ZLOAD。如果没有此权限,则Caché会生成 <PROTECT> 错误。
如果指定的例程不存在,则系统会生成错误。请注意,尝试ZLOAD例程失败会删除当前加载的例程。
此过程的所有后续错误都将附加当前加载的例程的名称。无论错误与例程是否有任何联系,都会发生这种情况,并且会在命名空间之间发生。
注意Namespaces
ZLOAD只能加载当前名称空间中存在的例程。一旦例程被加载,它将成为所有名称空间中该进程的当前加载例程。因此,可以从任何名称空间(而不仅仅是从其加载的名称空间)插入或删除行,显示,执行或卸载当前加载的例程。 ZSAVE将当前加载的例程保存在当前名称空间中。因此,如果ZLOAD命名空间不同于ZSAVE命名空间,则例程的修改后的版本将保存在发出ZSAVE时最新的命名空间中。更改不会保存在ZLOAD命名空间的例程版本中。
ZLOAD的常规行为
如果指定ZLOAD例程,则Caché在内存中的例程缓冲区池中查找该例程。如果例程不存在,则Caché将例程的ObjectScript目标代码版本加载到缓冲区之一中。 ObjectScript INT(中间)代码保留在当前名称空间的相应^ROUTINE全局变量中,但是如果进行编辑然后使用ZSAVE保存更改,则该代码将更新。
例如,ZLOAD MyTest加载例程MyTest的目标代码版本(如果尚未加载)。 MyTest例程必须在当前名称空间中。
在多用户环境中,应建立一个LOCK协议,以防止多个用户同时加载和修改同一例程。每个用户应在相应例程上发出ZLOAD之前获得排他锁。
如果省略例程,则ZLOAD将加载从当前设备(通常是键盘)输入的新代码行,直到通过输入空行(即,只需按)终止代码。该例程没有名称,除非使用后续的ZSAVE命令将其保存。
^rINDEX例行时间戳记和大小
可以使用^rINDEX全局来返回例程的MAC,INT和OBJ代码版本的本地时间戳和字符数,如以下终端示例所示:
DHC-APP>ZWRITE ^rINDEX("PHA.TEST.Command") ^rINDEX("PHA.TEST.Command","INT")=$lb("2020-07-24 22:54:27.995985",3132,1) ^rINDEX("PHA.TEST.Command","MAC")=$lb("2020-07-24 22:54:27.962484",3172) ^rINDEX("PHA.TEST.Command","OBJ")=$lb("2020-07-24 22:54:28",2760) DHC-APP>
MAC时间戳是修改后最后保存MAC代码的时间。 INT和OBJ时间戳是MAC代码上次编译的时间。修改INT代码版本后发出ZSAVE会更新INT和OBJ时间戳和字符计数。在不修改INT代码的情况下发出ZSAVE只会更新OBJ时间戳。
INT代码和^ ROUTINE全局变量
例程的ObjectScript INT(中间)代码存储在^ROUTINE全局变量中。 ^ROUTINE仅可以访问当前名称空间中的例程。 ^ROUTINE在磁盘上显示例程的INT代码版本,而不是当前加载的例程。
可以使用ZWRITE命令显示指定例程的INT代码:
ZWRITE ^ROUTINE("MyRoutine")
该显示包括例程MyRoutine的以下^ROUTINE下标:
- ^ROUTINE("MyRoutine",0)="65309,36923.81262":上次编译此例程的INT代码版本时的$HOROLOG格式的本地日期和时间。即使重新编译之前未对MAC代码进行任何更改,此时间戳也会更新。如果指定的例程是当前加载的例程,则如果对当前加载的例程进行了更改,则发出ZSAVE会更新该值。
w ^ROUTINE("PHA.TEST.Command",0) 65584,82467.995985
- ROUTINE("MyRoutine",0,0)=8:例程的INT代码版本中的行数。
DHC-APP>w ^ROUTINE("PHA.TEST.Command",0,0) 181
- ^ROUTINE("MyRoutine",0,1)="Main":例程的INT代码版本的第一行。在这种情况下,标签为Main。
DHC-APP>w ^ROUTINE("PHA.TEST.Command",0,1) AviationLetters
- ^ROUTINE("MyRoutine",0,2)=" WRITE ""This is line 2"",!": 例程的INT代码版本的第二行。在这种情况下,可执行的ObjectScript代码缩进一行。其他代码行遵循相同的模式。 ^ROUTIN不反映ZINSERT,并且ZREMOVE对当前例程的更改,直到使用ZSAVE保存这些更改为止。
DHC-APP>w ^ROUTINE("PHA.TEST.Command",0,2) Abc
如果例程是从MAC代码源加载的,则还会显示以下^ROUTINE下标:
- ^ROUTINE("MyRoutine","GENERATED")=1: 指示生成了INT代码。
DHC-APP>w ^ROUTINE("PHA.TEST.Command",0,"GENERATED")=1 1
-
^ROUTINE("MyRoutine","INC","%occStatus")="65301,60553":如果MAC版本包含#Include文件,则每个#Include文件都包含这些下标之一,并指定创建#Include文件时的时间戳。
-
^ROUTINE("MyRoutine","SIZE")=134: 源文件的INT代码版本中的字符数。
DHC-APP>w ^ROUTINE("PHA.TEST.Command",0,"SIZE") 3132
- ^ROUTINE("MyRoutine","MAC")="65309,36920.45721":上次保存例程的MAC版本时,采用$HOROLOG格式的本地日期和时间。仅当修改,保存并重新编译了MAC代码后,才会更新此时间戳。
DHC-APP>w ^ROUTINE("PHA.TEST.Command","MAC") 65584,82467.962484
可以使用管理门户查看和编辑^ROUTINE全局的内容。选择“系统资源管理器”,“全局”,然后从左侧列的名称空间下拉列表中选择所需的名称空间。
可以使用KILL命令删除ObjectScript INT(中间)代码:
KILL ^ROUTINE("MyRoutine")
如果该例程的INT代码不可用(已被杀死),该例程仍可以执行,但是无法在当前加载的例程中修改INT代码。 ZLOAD,ZINSERT和ZREMOVE不会发出任何错误,但是ZSAVE会失败,并显示错误。
ZLOAD和语言模式
加载例程后,当前语言模式将更改为加载的例程的语言模式。在被调用例程结束时,语言模式将恢复为调用例程的语言模式。但是,在加载ZLOAD的例程结束时,语言模式不会恢复为先前的语言模式。
示例下面的Terminal示例建立一个排他锁,然后加载相应的例程MyRoutine。它显示源代码的前10行,在第2行中添加一行ObjectScript代码,重新显示源代码,保存更改并释放锁:
DHC-APP>LOCK +^ROUTINE("PHA.TEST.Command") DHC-APP>ZLOAD PHA.TEST.Command DHC-APP>ZPRINT +1:+10 AviationLetters Abc WRITE "A is Abel",! WRITE "B is Baker",! WRITE "C is Charlie",! Def WRITE "D is Delta",! WRITE "E is Epsilon",! /* Not sure about E */ WRITE "F is Foxtrot",! PRINT +0:+3 DHC-APP>ZINSERT " WRITE ""Hello, World!""":+1 DHC-APP>ZPRINT +1:+11 AviationLetters WRITE "Hello, World!" Abc WRITE "A is Abel",! WRITE "B is Baker",! WRITE "C is Charlie",! Def WRITE "D is Delta",! WRITE "E is Epsilon",! /* Not sure about E */ WRITE "F is Foxtrot",! PRINT +0:+3 DHC-APP>ZSAVE DHC-APP>LOCK -^ROUTINE("MyRoutine") DHC-APP>d AviationLetters^PHA.TEST.Command Hello, World!A is Abel B is Baker C is Charlie D is Delta E is Epsilon F is Foxtrot AviationLetters WRITE "Hello, World!"
以下终端示例从设备dev加载第一个例程:
USER>OPEN dev USER>USE dev USER>ZLOAD