Progress 4GL内部过程如何访问主块定义的同名变量
结论
Progress 4GL(即OpenEdge ABL)的标识符解析遵循最近作用域优先规则:内部过程如果定义了和主程序块同名的局部变量,该变量会直接遮蔽外层主块的同名变量,原生没有提供类似其他语言的outer/global类关键字,直接穿透作用域访问被遮蔽的外层同名变量。
如果确实需要在定义了同名局部变量的内部过程中访问主块变量,可以通过以下几种可行方案实现:
- 方案1:通过主块层级的封装函数访问
主程序块中定义专属的取值、赋值函数,这类函数定义在主块作用域,内部绑定的永远是主块的变量,不受内部过程局部变量遮蔽影响。示例改造代码如下:
DEFINE VARIABLE myVariable AS INTEGER NO-UNDO. /* 主块定义访问主块变量的封装函数 */ FUNCTION getMainMyVariable RETURNS INTEGER (): RETURN myVariable. END FUNCTION. FUNCTION setMainMyVariable RETURNS LOGICAL (INPUT piNewVal AS INTEGER): ASSIGN myVariable = piNewVal. RETURN TRUE. END FUNCTION. PROCEDURE myProcedure1: MESSAGE "myProcedure1:" myVariable. END. PROCEDURE myProcedure2: DEFINE VARIABLE myVariable AS INTEGER NO-UNDO. /* 局部变量赋值 */ myVariable = 456. /* 通过封装函数访问主块的同名变量 */ MESSAGE "myProcedure2 局部变量值:" myVariable SKIP "myProcedure2 访问主块变量值:" getMainMyVariable(). /* 如需修改主块变量,调用set函数即可 */ RUN setMainMyVariable(789). END. myVariable = 123. RUN myProcedure1. RUN myProcedure2. /* 此处输出主块变量被修改后的值789 */ MESSAGE "主块最终myVariable值:" myVariable.
- 方案2:通过过程传参传递主块变量
调用内部过程时,把主块变量作为参数传入,内部过程通过参数接收主块变量的值,和自身的局部同名变量互不干扰。这种方式耦合度最低,是业务开发中最推荐的写法,示例代码如下:
DEFINE VARIABLE myVariable AS INTEGER NO-UNDO. PROCEDURE myProcedure2: DEFINE INPUT PARAMETER piMainMyVariable AS INTEGER NO-UNDO. DEFINE VARIABLE myVariable AS INTEGER NO-UNDO. myVariable = 456. MESSAGE "局部myVariable:" myVariable SKIP "传入的主块myVariable:" piMainMyVariable. END. myVariable = 123. /* 调用时把主块变量作为参数传入 */ RUN myProcedure2(INPUT myVariable).
- 方案3:使用共享变量显式声明作用域
主块将需要跨过程访问的变量声明为NEW SHARED,内部过程如果需要访问主块变量,要在定义自身局部同名变量前,先通过DEFINE SHARED VARIABLE绑定主块的共享变量。由于共享变量名必须和主块声明完全一致,和局部同名变量共存时需要提前把共享变量的值转存到其他别名变量中。这种方式耦合度高,变量修改链路不透明,排查问题成本高,非特殊场景不推荐使用。
注意:实际开发中最稳妥的做法是从编码规范层面约束,避免内部过程的局部变量和外层变量重名,从根源上消除变量遮蔽问题,大幅降低代码维护成本。
内容的提问来源于stack exchange,提问作者user13093022
相关产品推荐
相关产品推荐

