第四十三章 Caché 命令大全 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
不反映ZINSER
T,并且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