GUIDELINE 4.8
Program-Internal Names
ABAP_BACKGROUND
Program-internal names describe entities that are declared in the
program and are called within the program or called by other programs.
Typical examples include identifiers for data types and data objects as
well as methods and method interface parameters.
Program-internal declarations can be configured in different contexts
that all span a separate namespace. These contexts are arranged in a
sequence from local to global:
Local declarations in a procedure (
Method )
Declarations of instance components and static components in a class
Global declarations in the declaration part of a program
Here local declarations always hide the more global declarations of
higher contexts. Different types of declarations each span a separate
namespace in their context, except the class components, which are all
located in one single namespace, regardless of their type.
The identifiers used in ABAP programs are must comply with the syntactic
requirements for classes in Unicode programs (in accordance with the
rule Use ABAP Objects and the
rule Applying Default Settings to
Program Attributes ). In other words, the identifiers must begin with
a letter, which is followed other letters and numbers that can be
separated by underscores.
ABAP_RULE
Prevent program-internal names from being confused or overshadowed
Choose program-internal names that cannot be confused with ABAP words or
other declarations. In addition, a local name must not overshadow a more
global name. Global entities and interface parameters of procedures
should have a prefix for identification purposes.
ABAP_DETAILS
Besides using the general rule of assigning
meaningful names , it is also important
for program-internal declarations that you stick to the above rule of
eliminating human error (avoiding name confusion). Unlike a human
reader, the compiler usually knows exactly what an identifier is
referring to. Use the following prefixes to avoid the danger of unwanted
overshadowing and name confusion:
g_ for global data objects
i_ for IMPORTING parameters
e_ for EXPORTING parameters
c_ for CHANGING parameters
r_ for RETURNING parameters
You can also use compound identifiers and component selectors.
The following sections discuss the different aspects of program-internal
names in detail and with a systematic approach.
Confusion with ABAP Words
A basic rule in almost all naming specifications is that language
statements must not be used as names in the source code (assuming that
this is permitted by the syntax). The aim of this measure is to improve
readability by preventing confusion between statements and names. In
ABAP, however, it is difficult to strictly adhere to this rule, because
the vocabulary of the programming language is very extensive and is
continuously growing. In most cases, developers will not have memorized
all the ABAP words that occur in all the statements and statement
additions. Also, they cannot possibly know which words will be added in
future.
For this reason, it is not logical or feasible to completely prohibit
the use of ABAP words (ABAP keywords or additions) as names. Thanks to
the color highlighting in the ABAP Editor and the different
capitalization rules in operands and ABAP words (
Pretty Printer ), there is no
risk of confusion. If in doubt, you can always use the (!) character
directly in front of a name, to distinguish it from an ABAP word with
the same name in a statement.
A single ABAP word, however, usually does not represent a descriptive
name. Therefore, we recommend that you only use ABAP words as part of
combined names with underscores ( _ ), for instance,
account_class instead of class . Because the underscore is not
used in most ABAP words, it is usually a good idea to distinguish
between ABAP words and names . In some
very rare cases, the Compiler cannot differentiate between an ABAP word
and a name that is identical to the word. In these cases, the escape
character (!) must be specified.
Confusion between different declarations
In classes, all components are in the same namespace. Therefore, it is
not possible to have data types and attributes with the same name within
a class, in order to avoid confusion. In the other contexts, that is,
within procedures ( Methods ),
or for global declarations of an ABAP program, different declarations
generate different namespaces. Here it is possible to have data objects
and data types with the same name. Object types (local classes and
interfaces) are in the same namespace as data types.
To avoid confusion, we recommend that you use different names for
different entities, and that you do not use the same names for data
types and data objects. Exceptions to this rule are cases where the
meaning of a name is absolutely clear, for example, the declaration of a
helper variable:
DATA i TYPE i.
However, it should never be the case that a data object has the name of
a data type that is not the type of the object:
DATA i TYPE f.
DATA tadir TYPE trdir.
This is both confusing and dangerous!
Hiding declarations that are more global
The names in local contexts hide declarations with the same name in
contexts that are more global. In a method, for example, a data type
declared with TYPES hides an identically named data type of the
class. This data type then hides the identically named data type of the
program, which in turn hides an identically named data type from the
ABAP Dictionary.
Developers must ensure that a more global object (that should be used in
the current context) is not hidden. Conversely, a global object must not
be accidentally used instead of a local object. The reader of the source
code should always know what a name refers to. This means when you
assign names, you should try to make sure that the local names do not
hide names that are more global.
Following the KISS principle , it
is recommended that local names are different from global names, because
they do not follow their conventions. This mainly refers to the names in
global declarations of the current program or in the repository. For
example, a local class should never start with the cl_ prefix, a
local interface should never start with if_ prefix, and a local
data object should never start with the g_ prefix.
Within methods
In a method (in new function modules and subroutines, there should be
no local declarations ), there
is the danger that local names (including method parameters) can be
confused with more global names. Declarations within the implementation
can also be confused with method parameters.
To prevent local data objects in a method from being confused with
components of their own class, you can explicitly address class c
omponents using the name of the class and the class component selector
(= ), or using the object reference variable me and the instance
component selector (->) .
If there is a danger that identically named, predefined functions can be
confused, you should address the functional methods of its own class by
only using one of the selectors, if the methods are used in an operand
position. However, excessive use of selectors can make the source code
difficult to read. Therefore, you have to make individual assessments
here. This danger of confusion is only relevant for short method names,
however. For methods with names consisting of multiple words or names
that start with the prefixes set_ , get_ , or is_ ,
there is usually no risk of confusion. Methods should always have a
manageable size , and all declarations are
therefore always visible for the reader. Therefore, this simple rule
should be sufficient to make the method easy to read.
If the declaration of the method#s parameter interface is not visible in
the method implementation (as in local classes), it is useful to make an
additional distinction between local data and the method parameters. It
has become customary to use the prefixes mentioned earlier to achieve
this. An alternative prefix component l could also be considered
here for local data, but it ultimately represents redundant information.
Within classes
If you use class components, you can always avoid confusion by
addressing the class components using the name of the class and the c
lass component selector ( = ) or an object reference variable and
the instance component selector ( - ). The implementation of a
corresponding naming convention would lead to redundant information,
which would not improve readability and would be contradictory to the
basic KISS principle . This
especially applies to functional methods. Although these methods hide
identically named, predefined functions, it would be very unusual to
implement a prefix that characterizes a functional method as a method of
a class.
In programs: general
In the global declaration part of a program, you can create local
classes and interfaces, as well as global data types and data objects.
The names of local classes and interfaces do not follow the naming
conventions for global classes and interfaces. In other words, they
cannot start with cl_ or if_ , to ensure that no global
declarations are hidden. With regards to local data, you can consider
the naming convention lcl_ or lif_ , but this would be
redundant and not necessarily required, because a class/interface
without a prefix is always recognizable as a local class/local
interface. The use of lif_ may be useful for distinguishing a
local interface from a local class.
Data types should no longer occur in the
global declaration part of a
program. Global data objects are only required for communication between
ABAP and dynpro if classical dynpros
are used. Since these objects cannot names cannot be prefixed with a
program name, as with class attributes (absolute names are only possible
for data types and only in dynamic specifications), you must use the
g_ prefix for global data objects, to prevent confusion with
local data objects or class attributes in method implementations. Global
data objects can only exist in executable programs, module pools, and
function groups. Global classes and interfaces cannot contain any global
data objects. Therefore, a g_ prefix for class components or
interface components is definitely the wrong choice.
Note
Naming conventions are frequently established for names within the
source code that define specifications for naming, including potential
prefixes and suffixes. These specifications often get bogged down in
excessive formal strictness. Names created this way contain redundant
information, are difficult to maintain and often do not achieve the main
aim of readability and self-documenting sources. Therefore, we limited
our discussion to the naming-related aspects that we consider essential
and universal. Further specifications are only useful at the level of
development groups/organizations.
If prefixes and/or suffixes are used, it is common practice to store the
technical properties of the described object in these prefixes/suffixes.
Apart from the fact that we do not consider it necessary to specify
technical information in names, there are so many technical properties
of an object in ABAP that they cannot be mapped using simple rules for
short prefixes/suffixes. Or combinations of different technical
additions often cannot be interpreted uniquely. Some examples:
With regard to the data type of a data object, there are naming
conventions where "v" and "c" as prefixes stand for "variable" or
"constant" elementary data objects. Similarly, "s" and "t" as prefixes
stand for "structures" and internal "tables". The type property
"elementary" is wrongly equated with "variable" or "constant". If the
properties "static variable" and "sorted table" are also supposed to be
expressed using "s", this is very likely to cause mistakes with name
assignments. This makes it much harder to achieve the goal of readable,
self-documenting source codes.
With regard to the validity area or the context of a data
object, the naming conventions often stipulate the prefixes g_
and l_ for the names of global and local data objects. We
identified g_ for global data objects as the only convention that
is actually required for program-internal names. However, simultaneously
labeling all non-global objects with the prefix l_ for the local
validity area is completely redundant and does not result in any obvious
benefits. It would be actually be misleading to label static attributes
of classes as global, using the prefix g_ . These attributes are
only valid within the class and have completely different semantics than
global data objects. The use of these attributes does not indicate a
design weakness as it is generally the case for global data objects
today.
With regard to the method parameters , we identified the prefixes
i_ , e_ , c_ , and r_ for importing, exporting,
changing, and returning parameters as possible differentiators for
distinguishing from data objects declared in the method. Apart from
this, no further technical information needs to be expressed with
additional prefixes. With method parameters in particular, technical
information in prefixes tends to cause confusion rather than improve
readability. For example, a prefix is_ for "importing structure"
would conflict with the prefix is_ for "truth values", and a
prefix it_ for "importing table" could easily be understood as a
general abbreviation of "internal table". If the role the parameter
plays cannot be ascertained from the descriptive name of a parameter and
the procedure name, then the names assigned are completely wrong and/or
the procedure does not fulfill any clearly defined tasks. This type of
conceptual weakness cannot be fixed (even with technical prefixes).
In summary, we recommend that you should use name additions cautiously,
particularly additions with technical information. Of course, every
organization is free to use these conventions, which can supplement our
basic rules. In the ABAP environment - with its high versatility of
types, many contexts, the distinction between pass by reference and pass
by value - it is probably not an easy task to create a complete,
self-contained, consistent, technically correct, and # above all #
easy-to-understand set of rules for prefixes and suffixes. The known
results are just pure conventions that are usually incomplete and are
not always applicable.
Bad Example
The example shown below demonstrates how to hide names in different
contexts. The fact that no descriptive names were used for the data
objects (for the sake of simplicity) can be disregarded here.
DATA a1 TYPE string VALUE `a1 global`.
DATA a2 TYPE string VALUE `a2 global`.
DATA a3 TYPE string VALUE `a3 global`.
DATA a4 TYPE string VALUE `a4 global`.
DATA a5 TYPE string VALUE `a5 global`.
CLASS demo DEFINITION.
PUBLIC SECTION.
METHODS main
IMPORTING a1 TYPE string DEFAULT 'a1 imported'
RETURNING value(a6) TYPE string.
CLASS-DATA a1 TYPE string VALUE `a1 class`.
CLASS-DATA a2 TYPE string VALUE `a2 class`.
DATA a3 TYPE string VALUE `a3 class`.
DATA a4 TYPE string VALUE `a4 class`.
ENDCLASS.
CLASS demo IMPLEMENTATION.
METHOD main.
DATA a3 TYPE string VALUE `a3 local`.
DATA a4 TYPE string VALUE `a4 local`.
CONCATENATE a1 demo=>a2 me->a3 a4 a5
INTO a6 SEPARATED BY `, `.
ENDMETHOD.
ENDCLASS.
If you just consider the implementation of the main method in the
CONCATENATE statement, it is clearly evident only for the
demo= a2 and me- a3 operands that they are attributes of the
class and that a4 is a local data object of the method. It is only
possible in the general overview to see that a1 describes an
importing parameter, a5 describes a global data object of the
program, and a6 describes a returning parameter. The global data objects
a1 to a4 cannot be addressed in the method because they are hidden by
local data objects or attributes of the class.
Good Example
Unlike the source code above, the following source code includes the
previously discussed prefixes, to prevent hiding and to distinguish
method parameters from local data objects. Again, descriptive names were
not used here to focus on aspects that are essential for this example.
DATA g_a1 TYPE string VALUE `g_a1 global`.
DATA g_a2 TYPE string VALUE `g_a2 global`.
DATA g_a3 TYPE string VALUE `g_a3 global`.
DATA g_a4 TYPE string VALUE `g_a4 global`.
DATA g_a5 TYPE string VALUE `g_a5 global`.
CLASS demo DEFINITION.
PUBLIC SECTION.
METHODS main
IMPORTING i_a1 TYPE string DEFAULT 'i_a1 imported'
RETURNING value(r_a6) TYPE string.
CLASS-DATA a1 TYPE string VALUE `a1 class`.
CLASS-DATA a2 TYPE string VALUE `a2 class`.
DATA a3 TYPE string VALUE `a3 class`.
DATA a4 TYPE string VALUE `a4 class`.
ENDCLASS.
CLASS demo IMPLEMENTATION.
METHOD main.
DATA a3 TYPE string VALUE `a3 local`.
DATA a4 TYPE string VALUE `a4 local`.
CONCATENATE i_a1 demo=>a2 me->a3 a4 g_a5
INTO r_a6 SEPARATED BY `, `.
ENDMETHOD.
ENDCLASS.
All operands are now clearly recognizable in the CONCATENATE
statement. A prefix ( l_ ) can be implemented for the local names,
but this is unnecessary for two reasons:
The declaration is defined near the place of usage and is always visible
to the reader.
If you consistently use the selectors - and = to address
the attributes of a class, all names without a prefix and with no
specified class or a reference variable can be identified as local data
objects.
By applying the minimal naming convention used here, you can address all
data objects that are declared in the displayed source code section in
the method. Of course, the declaration of the global data objects is
only implemented to demonstrate hiding and how to prevent it. Global
data objects should no longer be
used in programs that do not work with classical dynpros.
Documentation extract taken from SAP system, � Copyright SAP AG. All rights reserved