第四十三章 Caché 命令大全 ZLOAD 命令

将例程加载到当前例程缓冲区中。

重点
  1. 终端输入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创建未命名的例程,作为终端程序中的当前例程:

  1. 在终端提示下,发出无参数ZLOAD命令。
  2. 在下面的行中,键入例程的第一个ObjectScript命令(不带引号),然后按Enter键两次。通常,此行是标签名称或标签名称,后跟可执行的ObjectScript代码。可执行的ObjectScript代码必须缩进。
  3. 在终端提示下,发出ZINSERT命令以向当前例程添加更多行。
  4. (可选)在终端提示下,发出ZSAVE例程以指定名称保存该例程。
  5. 完成后,使用无参数ZREMOVE卸载当前例程。

或者,可以使用ZINSERT创建一个未命名的例程作为终端中的当前例程。

ZLOAD带参数

ZLOAD例程将现有ObjectScript例程的INT代码版本从当前名称空间加载到例程缓冲区中,作为当前进程的当前例程。 INT代码不计算或不包含预处理程序语句。

ZLOAD在加载例程时会执行隐式无参数ZREMOVE。也就是说,ZLOAD删除任何先前加载的例程,将其替换为指定的例程。可以使用$ZNAME特殊变量来确定当前加载的例程。 ZLOAD加载例程时,它将行指针定位在例程的开头。

一旦加载,例程将一直是该过程的当前例程,直到使用ZLOAD命令显式加载另一个例程,使用无参数的ZREMOVE将其删除,或者使用DOGOTO命令隐式加载另一个例程。

只要例程是最新的,就可以编辑例程(使用ZINSERTZREMOVE命令),使用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全局的内容。选择“系统资源管理器”,“全局”,然后从左侧列的名称空间下拉列表中选择所需的名称空间。

第四十三章 Caché 命令大全 ZLOAD 命令_Caché

可以使用KILL命令删除ObjectScript INT(中间)代码:

  KILL ^ROUTINE("MyRoutine")

如果该例程的INT代码不可用(已被杀死),该例程仍可以执行,但是无法在当前加载的例程中修改INT代码。 ZLOADZINSERTZREMOVE不会发出任何错误,但是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