3 Reasons Why ABAP Exporting Parameters Are Evil

In ABAP, it is possible to use several types of parameters: importing, exporting, changing and returning. Here I list some reasons of why you should avoid using exporting parameters.

1. You can have multiple exporting parameters

In a method, you can only have one returning parameter. By contrast, you can have multiple exporting parameters. This may lead to a method doing more than one thing, and as Robert Martin noted in his excellent book ‘Clean Code’, this is a code smell¹: "Functions should do one thing. They should do it well. They should do it only.".

2. An exporting parameter is, behind the scenes, a changing parameter. This may lead to inconsistencies

Both changing and exporting parameters are passed by reference. Being so, inside the method they are directly handled with their real value, acting as pointer to the actual value. Their values are also modified even if the method leave early due to an exception². Consider the following examples:

First, we have a method with an importing and returning parameter:
METHODS foo_with_returning
IMPORTING
iv_bar TYPE i
RETURNING
VALUE(rv_return) TYPE i
RAISING
zcx_an_exception,
METHOD foo_with_returning.
"You can't directly assign values to a importing parameter, so we need an auxiliar variable
DATA(baz) = iv_bar.
baz = baz + 3.
RAISE EXCEPTION TYPE zcx_an_exception.
baz = baz + 2.
ENDMETHOD.
When we run the following unit test, it passes:
METHOD test_with_returning.
DATA bar TYPE i.
bar = 5.
TRY.
DATA(qux) = foo_with_returning( bar ).
CATCH zcx_an_exception.
ENDTRY.
"We expect bar to keep its value, despite the exception raise.
cl_abap_unit_assert=>assert_equals(
exp = 5
act = bar
).
"This test passes
ENDMETHOD.
Now consider this example where we have a method with an exporting parameter:
METHODS foo_with_exporting
EXPORTING
ev_qux TYPE i
RAISING
zcx_an_exception.
METHOD foo_with_exporting.
"It is possible to directly change the exporting parameter value.
ev_qux = ev_qux + 3.
RAISE EXCEPTION TYPE zcx_an_exception.
ev_qux = ev_qux + 2.
ENDMETHOD.
This unit test fails:
METHOD test_with_exporting.
DATA bar TYPE i.
bar = 5.
TRY.
foo_with_exporting( IMPORTING ev_qux = bar ).
CATCH zcx_an_exception.
ENDTRY.
"We expect bar to keep its value, but it doesn't.
cl_abap_unit_assert=>assert_equals(
exp = 5
act = bar
).
"This test fails, the actual value is 8.
ENDMETHOD.
This is a simple example, but it demonstrates the possible undesirable outcomes of using an exporting parameter, if it is misused (very common with less experienced programmers). Consider we had a more complicated scenario, this could lead to an inconsistent state (e.g. persisting the bar variable with an incorrect value).

3. Readability

Code should be easy to read, I find the importing/returning parameter syntax much cleaner:
"Returning
DATA(qux) = foo( bar ).
"Exporting
foo(
EXPORTING
iv_bar = bar
IMPORTING
ev_qux = qux
).


So, as a rule of thumb, avoid exporting parameters. They are evil!
P.S.: Special thanks to Paulo Büttenbender and Michel Henrich for the peer review for this post.
¹ Martin, Robert C. Clean code: a handbook of agile software craftsmanship. Pearson Education, 2009. Pages 35 and 302
² Keller, Horst, and Wolf Hagen Thümmel. Official ABAP Programming Guidelines. Galileo Press, 2010. Page 293

Comments