前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Caché 变量大全 $ESTACK 变量

Caché 变量大全 $ESTACK 变量

作者头像
用户7741497
发布2022-05-10 12:23:41
3300
发布2022-05-10 12:23:41
举报
文章被收录于专栏:hml_知识记录

Caché 变量大全 $ESTACK 变量

包含从用户定义的点保存在调用堆栈上的上下文帧的数量。

大纲

代码语言:javascript
复制
$ESTACK
$ES

描述

$ESTACK包含从用户定义的点为JOB保存在调用堆栈上的上下文帧的数量。可以通过使用new命令创建$ESTACK的新副本来指定这一点。

$ESTACK特殊变量类似于$STACK特殊变量。两者都包含当前保存在JOB或程序的调用堆栈中的上下文框架的数量。更改上下文时,Caché会递增并恢复两者。主要区别在于,可以随时使用NEW命令将$ESTACK计数重置为零。无法重置$STACK计数。

上下文框架和调用堆栈

启动Caché映像时,在将任何上下文保存到调用堆栈之前,$ESTACK$STACK的值均为零。每次例程使用DO调用另一个例程时,系统都会将当前正在执行的例程的上下文保存在调用堆栈中,递增$ESTACK$STACK,并在新创建的上下文中开始执行被调用例程。被调用的例程可以依次调用另一个例程,依此类推。每次调用另一个例程时,Caché都会递增$ESTACK$STACK并将更多保存的上下文放在调用堆栈中。

发出DO命令,EXECUTE命令或对用户定义函数的调用会建立新的执行上下文。不会发出GOTO命令。

DO命令,XECUTE命令或用户定义的函数引用创建新上下文时,Caché将增加$STACK$ESTACK的值。当QUIT命令导致上下文退出时,Caché从调用堆栈中恢复以前的上下文,并减小$STACK$ESTACK的值。

不能使用SET命令修改$ESTACK$STACK特殊变量。尝试这样做会导致<SYNTAX>错误。

创建$ESTACK

可以使用NEW命令在任何上下文中创建$ESTACK的新副本。 Caché采取以下行动:

  • 保存$ESTACK的旧副本。
  • 创建新的$ESTACK副本,其值为零(0)。

这样,可以将特定上下文建立为$ESTACK级别0上下文。当使用DOXECUTE或用户定义的函数创建新的上下文时,Caché会将此$ESTACK值递增。但是,当退出创建新$ESTACK的上下文时($ESTACK处于级别0),Caché会还原$ESTACK的先前副本的值。

示例

以下示例显示了$ESTACK上的NEW命令的作用。在此的示例MainRoutine显示$STACK$ESTACK的初始值(它们是相同的值)。然后,它调用Sub1。该调用将增加$STACK$ESTACKNEW命令创建一个值为0的$ESTACKSub1调用Sub2,递增$STACK$ESTACK。返回MainRoutine将恢复$STACK$ESTACK的初始值:

代码语言:javascript
复制
/// d ##class(PHA.TEST.SpecialVariables).ESTACK()
ClassMethod ESTACK()
{
Main
    WRITE !,"Initial: $STACK=",$STACK," $ESTACK=",$ESTACK
    DO Sub1
    WRITE !,"Return: $STACK=",$STACK," $ESTACK=",$ESTACK
    QUIT
Sub1
    WRITE !,"Sub1Call: $STACK=",$STACK," $ESTACK=",$ESTACK
    NEW $ESTACK
    WRITE !,"Sub1NEW: $STACK=",$STACK," $ESTACK=",$ESTACK
    DO Sub2
    QUIT
Sub2
    WRITE !,"Sub2Call: $STACK=",$STACK," $ESTACK=",$ESTACK
    QUIT
}
代码语言:javascript
复制
DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK()
 
Initial: $STACK=1 $ESTACK=1
Sub1Call: $STACK=2 $ESTACK=2
Sub1NEW: $STACK=2 $ESTACK=0
Sub2Call: $STACK=3 $ESTACK=1
Return: $STACK=1 $ESTACK=1

下面的示例演示了如何通过发出DOXECUTE命令在创建新上下文时增加$ESTACK的值,并在退出这些上下文时减小其值。它还显示GOTO命令不会创建新上下文或增加$ESTACK

代码语言:javascript
复制
/// d ##class(PHA.TEST.SpecialVariables).ESTACK1()
ClassMethod ESTACK1()
{
Main
    NEW $ESTACK
    WRITE !,"Initial Main: $ESTACK=",$ESTACK   // 0
    DO Sub1
    WRITE !,"Return Main: $ESTACK=",$ESTACK   // 0
    QUIT
Sub1
    WRITE !,"Sub1 via DO: $ESTACK=",$ESTACK  // 1
    XECUTE "WRITE !,""Sub1 XECUTE: $ESTACK="",$ESTACK"   // 2
    WRITE !,"Sub1 post-XECUTE: $ESTACK=",$ESTACK   // 1
    GOTO Sub2
Sub1Return
    WRITE !,"Sub1 after GOTO: $ESTACK=",$ESTACK  // 1
    QUIT
Sub2
    WRITE !,"Sub2 via GOTO: $ESTACK=",$ESTACK   // 1
    GOTO Sub1Return
}
代码语言:javascript
复制
DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK1()
 
Initial Main: $ESTACK=0
Sub1 via DO: $ESTACK=1
Sub1 XECUTE: $ESTACK=2
Sub1 post-XECUTE: $ESTACK=1
Sub2 via GOTO: $ESTACK=1
Sub1 after GOTO: $ESTACK=1
Return Main: $ESTACK=0

注意

终端提示的上下文级别

从程序调用的例程与在终端提示下使用DO命令调用的例程在不同的上下文级别开始。在终端提示下输入DO命令时,系统会为该例程创建一个新的上下文。

调用的例程可以通过建立$ESTACK Level 0上下文进行补偿,然后对所有上下文级引用使用$ESTACK

请考虑以下例程:

代码语言:javascript
复制
/// d ##class(PHA.TEST.SpecialVariables).ESTACK2()
ClassMethod ESTACK2()
{
START
    ; 建立$ESTACK 0级上下文
    NEW $ESTACK
    ; 显示$STACK上下文级别
    WRITE !,"$STACK level in routine START is ",$STACK
    ; 显示$ESTACK上下文级别并退出
    WRITE !,"$ESTACK level in routine START is ",$ESTACK
    QUIT
}

从程序运行Start时,会看到以下显示:

代码语言:javascript
复制
$STACK level in routine START is 0
$ESTACK level in routine START is 0

当在终端提示符下发出do^start命令来运行START时,会看到以下显示:

代码语言:javascript
复制
DHC-APP>d ##class(PHA.TEST.SpecialVariables).ESTACK2()
 
$STACK level in routine START is 1
$ESTACK level in routine START is 0

$ESTACK和错误处理

当错误处理程序必须将调用堆栈展开到特定上下文级别时,$ESTACK在错误处理期间特别有用。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Caché 变量大全 $ESTACK 变量
  • 大纲
  • 描述
    • 上下文框架和调用堆栈
      • 创建$ESTACK
      • 示例
      • 注意
        • 终端提示的上下文级别
        • $ESTACK和错误处理
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档