局部声明掩盖了同名的全局变量

Local declaration obscuring a global variable of same name

今天在旧代码中遇到声明困境

考虑以下片段:

REPORT ZPROGRAM.

DATA: v_data TYPE field.

FORM code_block.
  SELECT SINGLE datum FROM db INTO @v_data WHERE field = @value.
  SELECT SINGLE datum FROM db INTO @DATA(v_data) WHERE field = @value.
ENDFORM. 

这段代码没有错误。

现在,第一个 select 语句检索数据 (sy-subrc = 0)V_DATA 未填充数据。我希望 V_DATA 反映数据,因为此时它是一个全局变量。

V_DATA 的内联声明是否掩盖了它的全局定义,因为两个变量同名?但是为什么会发生这种情况,因为内联声明发生在全局变量的可见性之后?

答案似乎比我最初想的“复杂得多”。

我的测试报告是ZTEST:

REPORT ztest.

DATA: v_data TYPE field.

FORM code_block.
  v_data = 'A'.                           " <==== affects the global variable
  CONCATENATE 'B' 'b' INTO DATA(v_data).  " <==== affects the local variable
ENDFORM.

START-OF-SELECTION.
  PERFORM code_block.

我调试这两个变量(使用后端调试器):

  • V_DATA,查看局部变量
  • (ZTEST)V_DATA,查看全局变量

我在逐步调试时看到了这些值:

Right after execution of this line          V_DATA      (ZTEST)V_DATA
 v_data = 'A'.                                          A
 CONCATENATE 'B' 'b' INTO DATA(v_data).     Bb          A

用这个代码也是一样的:

DATA: v_data TYPE field.

FORM code_block.
  v_data = 'A'.                     " <==== affects the global variable
  DATA: v_data TYPE field.
  CONCATENATE 'B' 'b' INTO v_data.  " <==== affects the local variable
ENDFORM.

START-OF-SELECTION.
  PERFORM code_block.

来自 DATA(...) 上的 ABAP documentation

The declared variable is visible statically in the program as of DATA(var) and is valid in the current context. The declaration is made when the program is compiled, regardless of whether the statement is actually executed. [...]

A valid statement with an inline declaration of a variable can generally be interpreted as a short form for a declaration statement used as a direct prefix.

DATA var TYPE ...
... var ...

Deviations from this rule occur only if an identically named data object of a more global context is used in the same statement. This is still valid in the statement and is only hidden after the statement.

稍微编译一下:标识符引用更全局上下文 的数据对象,直到到达DATA(...) 声明。从那时起,标识符指的是内联声明的变量。 FORM 语句引入了新的上下文。

也就是说,根据 naming guidelines:

,隐藏通常是一种不好的做法

Choose program-internal names that cannot be confused with ABAP words or other declarations. In addition, a local name must not obscure a more global name