Figure 168: Parameter Passing (Motivation 2)
You can address all (global) variables defined in the main program from a
subroutine. But, in order to call up a subroutine for a specific situation with
different data objects for each situation, you do not use global variables in
the subroutine but placeholders, which are replaced with the required global
variables at the time the subroutine is called. These placeholders are called formal
parameters and together they form the interface of the subroutine, which has to
be declared when the subroutine is defined.
When the subroutine is called, formal parameters must be specialized by means of
corresponding global variables (actual parameters), in order to implement the
reference of the subroutine processing to real variables. This assignment of actual
parameters to formal parameters when calling a subroutine is called parameter
passing.
3
Figure 169: Ways of Passing Interface Parameters
They way these variables of the main program are passed to the formal parameters
of the subroutine is called passing type and is specified for each parameter in
the interface of the subroutine.
There are three passing types:
Call by Value
A copy is made of the actual parameter. This copy is assigned to the formal
parameter. If in the subroutine a value is assigned to the corresponding
formal parameter, this value will actually be assigned to a copy of the formal
parameter and not its original.
You use this pass type, to make the value of a global variable available to
the subroutine (in the form of a variable copy) without making it possible
to change the respective global variable (protecting the original). Please
note, however, that creating copies, especially for large internal tables, can
be time-consuming.
With this transfer type, the same applies as for call by value. However, at
the regular end of the subroutine, the value that was changed to this point
is written back to the original. If the program is prematurely terminated
through a STOP statement or a user message of type E, the writing back
of the values is suppressed.
You use this pass type to transfer the value of a global variable to the
subroutine and to have the fully processed final value of the copy written
back to the original. But note that the creation of copies and the writing back
of values can be time-consuming, especially for large internal tables.
Call by reference
The actual parameter is assigned directly to the formal parameter. This
means that value assignments to the formal parameter are executed directly
on the actual parameter.
You use this pass type if you want to run the subroutine processing directly on
the specified actual parameter. It is popular for avoiding the time-consuming
creation of copies for large internal tables.
Figure 170: Defining and Calling Subroutines
A subroutine is introduced with FORM.
The name and the interface of the subroutine are to be specified behind FORM.
The statements of the subroutine follow.
TheENDFORM statement concludes the subroutine.
In the interface definition you list the formal parameters of the subroutine (here:
f1, f2, f3) and type them if necessary. The required pass type has to be specified
for each parameter:
Call by value
You list each of the formal parameters that is supposed to have the pass type
call by value (here: f1) with the VALUE prefix in the USING section.
(Refer to the above graphic for the syntax.)
Call by value and result
You list each of the formal parameters that is supposed to have the pass
type call by value and result (here: f1) with the VALUE prefix in the
CHANGING section. (Refer to the above graphic for the syntax.)
Call by reference
You list each of the formal parameters that is supposed to have the pass type
call by reference (here: f3) without the VALUE prefix in the CHANGING
section. (Refer to the above graphic for the syntax)
Note: A parameter without VALUE prefix, but placed in the USING
section also has the pass type call by reference. However, this
declaration syntax only makes sense for formal parameters that are
passed to larger internal tables, which are not to be changed in the
subroutine (documentation via USING) but are to be passed using
call by reference in order to avoid making time-consuming copies.
When the subroutine is called, the actual parameters to be transferred without
VALUE prefix are specified under USING or CHANGING. The order of
specification determines their assignment to the formal parameters. In the example
in the above graphic, a is passed to f1, b to f2, and c to f3.
Figure 171: Typing the Interface Parameters
A formal parameter is typed generically, if it is typed using TYPE ANY or not
typed at all. Actual parameters of any type can be transferred to such a parameter.
At runtime, the type of the actual parameter is determined and assigned to the
formal parameter (type inheritance) when the subroutine is called. However, if
the statements in the subroutine are not suited to the inherited type, a runtime
error may occur (type conflict). Hence, generic typing should only be used if the
type of the actual parameter is yet to be determined when the program is created
or if it can vary at runtime (dynamic programming).
You implement the concrete typing of a formal parameter by specifying a global
or built-in type in the TYPE addition. In doing so, you specify that only actual
parameters of the specified type are to be passed to the subroutine. A violation of
the type consistency between formal and actual parameters is already picked up in
the syntax check. This increases the stability of your program as type conflicts in
statements within the subroutine are prevented.
If you type with the standard types P, N, C or X, the missing characteristic field
length is not inherited from the actual parameter until runtime. You achieve
a complete type assignment with this type (i.e., including the field length) by
defining and specifying locally defined types.
You must type formal parameters for structures and internal tables so that you can
access the corresponding components. The components of structure parameters are
known in the subroutine, as a result of the assigned type, so that you can address
these components with the usual syntax. The typing of table parameters enables
you to address these as internal tables using the usual syntax in the subroutine.
Hint: Larger internal tables should be transferred by call by reference
in order to avoid time consuming copies.
Figure 173: Visibility of Global and Local Data Objects
Variables defined in the main program are global data objects. They are visible
(can be addressed) in the entire main program in every subroutine called.
Variables defined within a subroutine are called local, as they only exist in the
relevant subroutine - just like the formal parameters. The memory for formal
parameters and local data objects is only allocated during the subroutine run and
released again after execution.
The formal parameters and local data objects of a subroutine can not have the
same names. If there is a global data object with the same name as a formal
parameter or a local data object, then the formal parameter or local data object is
addressed within the subroutine and the global data object is addressed outside
the subroutine. This is called hiding rule. Within a subroutine the local data
objects hides the global one with the same name.
To clearly label your program-internal objects you
could, for example, use the following prefixes:
f_... for formal parameters and
l_... for a local data object.
Figure 174: Syntax Example: Passing an Internal Table
In the above syntax example, the internal table it_flightinfo and the global variable
carrid are passed by means of call by reference, even though they are not changed
in the subroutine. The advantage of this is that no copies have to be made.
To loop through the internal table, you need a work area with a compatible line
type. This is locally defined in the subroutine with reference to the table parameter
f_itab. The reference is possible because f_itab is typed in the interface of the
subroutine.
You can have the PERFORM statement for calling a subroutine generated into
your source code. First, define the subroutine and then save your main program.
The newly-defined subroutine appears in the navigation area. Move it to the
required call point in your program by means of drag & drop. All you have to do
is replace the formal parameters in the generated source code with corresponding
actual parameters.
(Alternatively, the call generation can also be implemented using the Pattern
pushbutton in the ABAP editor.)
The advantage of the call generation is that it is impossible to forget or mix
parameters.
Hiç yorum yok:
Yorum Gönder