A few weeks back, I was debugging a seemingly very weird error. Without getting into too much details, what turned out to be the cause for my issue is that I had a variable declared in a loop. Then, in an
if block, the variable was assigned some value (given that the
if condition evaluated to true, obviously). Later in the loop, some operations were performed using this variable. And this is what turned out to be the problem.
I found out that the value
from the previous loop is retained when the
if block is not entered in. When I did think about it, it wasn’t so weird anymore. In ABAP, variable declarations are method-scoped, not block-scoped (as in, for example, Java). This means that the following code does
not work in Java (we get an error: cannot find symbol
a😞
public class MyDemoClass {
public static void main(String []args){
if (false) {
int a = 5;
}
a = 7;
System.out.println(a);
}
}
But the same logic is completely valid in ABAP (
although a bad practice😞
class zcl_my_demo_class definition public final create public.
public section.
interfaces:
if_oo_adt_classrun.
endclass.
class zcl_my_demo_class implementation.
method if_oo_adt_classrun~main.
if abap_true = abap_false.
data(a) = 5.
endif.
a = 7.
out->write( a ).
endmethod.
endclass.
Therefore, because of this, if we initialize variables in a loop, they are only given an initial value the first time, and every next iteration, the value from the previous iteration is kept. Again, when you do think about it, this is not strange, but, in general, information on the internet about ABAP is unfortunately not plentiful. So, I figured this may save some frustration for a developer somewhere in the future, if they land here after a Google search
😊 (and, on the overall, making information about ABAP more accessible, and thus helping to develop its ecosystem is something I am trying to do!).
So, based on the above, the following logic:
class zcl_my_demo_class definition public final create public.
public section.
interfaces:
if_oo_adt_classrun.
endclass.
class zcl_my_demo_class implementation.
method if_oo_adt_classrun~main.
data(i) = 0.
while i <> 3.
data my_var type i.
if i = 1.
my_var = 7.
endif.
if my_var is initial.
out->write( |we have an initial variable!| ).
else.
out->write( |we have { my_var } as value for the variable!| ).
endif.
i = i + 1.
endwhile.
endmethod.
endclass.
Will lead to the following output:
We have an initial variable!
We have 7 as value for the variable!
We have 7 as value for the variable!
I.e., in the first iteration (i = 0), we create the new variable
my_var. It is currently initial. Nothing is assigned to it even after the
if block, because as mentioned at this point
i is 0. In the second iteration (i = 1), the variable
my_var is already there, but it is still initial, because nothing was assigned to it during the last iteration. However, this time, we do enter the
if block, and assign
7 to
my_var. In the third and last iteration (i = 2), the variable
my_var is already there, and it has already been assigned a value in the last iteration, so currently
my_var is 7, even though the if block is not executed.
If you would like to get around this, one suggestion from my side is to do the following:
data(my_var) = value i( ).
As opposed to:
data my_var type i.
This retains the benefit of not having to assign a literal of the initial value (i.e. 0 in this case) and, what is different, is that now, the initial value is re-assigned every loop. Now, we have the following output:
We have an initial variable!
We have 7 as value for the variable!
We have an initial variable!
To conclude, and to also repeat, this may seem obvious for most ABAP developers when being seen like this, but it can be the source of seemingly weird issues, especially in an old code, written before inline declarations were a thing in ABAP. So hopefully, this saves a bit of time in the future for at least some developers… and also spreads some ABAP knowledge to non-ABAP developers in the process
😊