条件被捕获时的操作

当当前已启用条件陷阱 (ON) 并且发生指定的条件时,将自动处理 CALL trapname 或 SIGNAL trapname 指令,而不是通常的控制流。

可以在 CALL ON 或 SIGNAL ON 指令的 NAME 子关键字后指定 trapname 。 如果未指定 trapname,那么将使用条件本身的名称 (ERROR , FAILURE , HALT , NOTREADY , NOVALUE 或语法)。

例如,指令 call on error 对 ERROR 条件启用条件陷阱。 如果发生此情况,那么将调用由名称 ERROR 标识的例程。 如果发生此情况,那么指令 call on error name commanderror 将启用陷阱并调用例程 COMMANDERROR。

在捕获条件后,事件序列根据是处理 SIGNAL 还是 CALL 而有所不同:
  • 如果所执行的操作是 SIGNAL ,那么将立即停止执行当前指令,将禁用该条件 (设置为 OFF) ,并且将以与通常完全相同的方式执行 SIGNAL (请参阅 SIGNAL)。

    如果要捕获任何新出现的条件,那么需要针对该条件的新 CALL ON 或 SIGNAL ON 指令以在达到标签时重新启用该条件。 例如,如果在出现语法条件时启用了 SIGNAL ON 语法,那么如果找不到 SIGNAL ON 语法标签名称,那么将发生通常的语法错误终止。

  • 如果执行的操作是 CALL (只能在子句边界处发生) ,那么将以通常的方式执行 CALL (请参阅 CALL) ,但调用不会影响特殊变量 RESULT。 如果例程应该返回任何数据,那么将忽略返回的字符串。

    因为这些情况 (ERROR , FAILURE 和 HALT) 可能在执行解释指令期间出现,所以如果使用了 CALL ON ,那么可能会中断并在稍后恢复执行解释指令。

    随着条件的提高,在进行 CALL 之前,会将条件陷阱置于延迟状态。 此状态持续存在,直到从 CALL 返回,或者对该条件执行显式 CALL (或 SIGNAL) ON (或 OFF) 为止。 此延迟状态可防止在为处理条件陷阱而调用的例程启动时出现过早的条件陷阱。 当条件陷阱处于延迟状态时,它将保持启用状态,但是如果再次出现该条件,那么将忽略该条件 (对于 ERROR , FAILURE 或 NOTREADY) 或 (对于其他条件) 任何操作 (包括更新条件信息) ,直到发生下列其中一个事件为止:
    1. 处理延迟条件的 CALL ON 或 SIGNAL ON。 在这种情况下,将在处理新的 CALL ON 或 SIGNAL ON 指令之后立即执行 CALL 或 SIGNAL。
    2. 对于延迟条件,将处理 CALL OFF 或 SIGNAL OFF。 在这种情况下,条件陷阱处于禁用状态,并且条件的缺省操作发生在 CALL OFF 或 SIGNAL OFF 指令的末尾。
    3. RETURN 是从子例程中产生的。 在这种情况下,不再延迟条件陷阱,将立即再次调用子例程。
    从 CALL 返回时,将恢复原始执行流 (即,该流不受 CALL 影响)。
    注:
    1. 编写语法陷阱例程时必须格外小心。 在可能的情况下,将例程放在程序开头附近。 这是必需的,因为如果存在某些扫描错误 (例如缺少结束注释) ,那么可能找不到陷阱例程标签。 此外,陷阱例程不应包含任何可能导致扫描更多出错程序的语句。 这方面的示例是对内置函数的调用,其中名称周围没有引号。 如果内置函数名为大写并括在引号内,那么 REXX 将直接转至函数,而不是搜索内部标签。
    2. 在所有情况下,检测时都会立即提出条件。 如果 SIGNAL ON 捕获条件,那么将结束当前指令 (如果需要)。 因此,可能仅部分处理发生事件的指令。 例如,如果在赋值中的表达式求值期间提出语法,那么不会执行赋值。 请注意,针对 ERROR , FAILURE , HALT 和 NOTREADY 陷阱的 CALL 只能在子句边界发生。 如果这些条件出现在路由指令的中间,那么可能中断执行路由的解释,稍后将恢复执行。 类似地,其他指令 (例如 DO 或 SELECT) 可能在子句边界被 CALL 临时中断。
    3. 每个条件陷阱的状态 (ON , OFF 或 DELAY ,以及任何 trapname) 保存在子例程的条目上,然后在 RETURN 上恢复。 这意味着可以在子例程中使用 CALL ON , CALL OFF , SIGNAL ON 和 SIGNAL OFF ,而不影响调用者设置的条件。 有关在子例程调用期间保存的其他信息的详细信息,请参阅 CALL 指令 (CALL)。
    4. 当 CALL 调用外部例程时,条件陷阱的状态不受影响,即使该外部例程是 REXX 程序也是如此。 在进入任何 REXX 程序时,所有条件陷阱都具有初始设置 OFF。
    5. 在交互式跟踪期间处理用户输入时,所有条件陷阱都将临时设置为 OFF。 这可防止任何意外的控制传输; 例如,如果用户在 SIGNAL ON NOVALUE 处于活动状态时意外使用未初始化的变量。 出于同样的原因,交互式跟踪期间的语法错误不会导致程序退出,而是被特别捕获,然后在给出消息后被忽略。
    6. 系统接口在程序开始执行之前或程序结束之后检测到某些执行错误。 语法上的信号不能捕获这些错误。
    请注意, label 是由单个符号后跟冒号组成的子句。 任何数目的连续子句都可以是标签; 因此,允许在另一类型的子句之前使用多个标签。