Mind the shadows!
A quick search in your favourite web browser with the phrase “scope in the ABAP programming language” returns a large listing of questions and opinions about the roles and employment future of ABAP programmers. Whereas a similar search with the phrase “scope in the Rust programming language” or “scope in the Java programming language” returns a listing of articles discussing the validity and visibility of types and variables. Whilst the employment future of ABAP developers is a topic worthy of discussion, the apparently not such a popular topic – scoping of variables and types in ABAP – is the focus of this little blog post.
Within an ABAP program, variables can be defined as attributes of local classes or within methods or procedures like subroutines. These local variables have visibility only within the scope of the local classes or procedures. Variables defined in the global declaration of an ABAP program have program wide scope and validity. They are typically called global variables. A similar scoping exists for types in an ABAP program. Types can be defined with local validity within a local class, method or procedure or globally declared in the ABAP program itself.
When it comes to types, we shouldn’t forget about the types that are defined in the (global) repository of the ABAP system. The persistent data elements, structures and tables definitions from which many of our program variables derive their type information. Nor should we overlook global classes – another type of object which can be utilised within our programs as a reference type for variables.
If I ignore the visibility rules of packages, from the perspective of the run of the mill ABAP program, we have three common scoping areas for variables and types. I’ll call them levels – numbered as follows:
- Globally defined outside of the program in the system repository, like data elements, types, structures and other programs like global classes
- Globally defined in a program
- Locally defined in a local class or procedure
At the top of the list – level 1 – we have the objects with the widest visibility, whilst at the bottom we have the objects with the narrowest of validity and visibility. All clear? It seems so, but that which is apparently clear becomes a little murkier when we step into the shadows.
Variable or type shadowing occurs when a variable or type declared within a certain scope has the same name as a variable declared in an outer scope. The key part here is the same name. In ABAP, the rules are pretty simple – a type or variable defined locally overshadows a type of the same name defined in broader scopes – like globally in the program or in the global repository. In my list above, levels with larger numbers can overshadow types defined on levels with lower numbers.
Since ABAP is a strongly typed language, during compilation the compiler needs to determine the types of all variables. Despite all the places where types can be defined and the opportunity for shadowing, the compiler works it out.
Whilst the compiler is smart – often humans are not so smart – and poor choices in names for types and local classes leads to lots of confusion for humans when trying to work out what is going on.
For those who prefer to read ABAP language than English, a very small example of what I’m talking about. And yes, whilst I’ve changed the code to protect the guilty, it has all the elements of some code I stumbled across this week.
REPORT SAPFZZZ009. TYPES CAUFVD TYPE AFIH. CLASS CL_ABAP_TIMEFM DEFINITION. PUBLIC SECTION. CLASS-METHODS SAY_HELLO RETURNING VALUE(RESULT) TYPE STRING. ENDCLASS. CLASS CL_ABAP_TIMEFM IMPLEMENTATION. METHOD SAY_HELLO. TYPES LOCAL_ORDER TYPE CAUFVD. DATA LOCAL_ORDER TYPE LOCAL_ORDER. ENDMETHOD. ENDCLASS. START-OF-SELECTION. CL_ABAP_TIMEFM=>SAY_HELLO( ). DATA PM_ORDER_HEADER TYPE CAUFVD.
I bet at least some of you had a little mental jolt reading the code. I’d suggest such code requires a higher degree of mental effort to work out what is going on than it needs.
So, to ease the burden upon those who will inherit our programs and to keep your friendly code reviewer on your side, I’d encourage you to consider the following tips when writing your programs:
- Don’t give program or local types the same name as those in the system repository
- Don’t define local classes in your programs with the same name as those in the system repository
- And, in all things, value clarity of intention in your code.
Avoid confusion and Mind the shadows!