IMPORTING parameter pass-by-value and pass-by-reference
Dear community, I recently read an ABAP source code. So far nothing special. That happens to me from time to time 😉 While reading, I noticed that someone possibly assumed that an object which was passed using the IMPORTING parameter cannot be changed at all.
Mmh, I wasn’t sure about the assumption because I know it a bit differently. So I’ve made a little example and put it along with my thoughts together in this blog. Just to check. Perhaps I’m wrong. Maybe it’s all clear to everyone, but maybe not. Then this blog is all the more valuable. So please take a look at this example first.
REPORT ztest. CLASS lcl_object DEFINITION FINAL CREATE PUBLIC. PUBLIC SECTION. DATA mv_color TYPE string. METHODS constructor. ENDCLASS. CLASS lcl_object IMPLEMENTATION. METHOD constructor. ENDMETHOD. ENDCLASS. CLASS lcl_example DEFINITION FINAL CREATE PUBLIC. PUBLIC SECTION. METHODS constructor. METHODS pass_by_reference IMPORTING io_object TYPE REF TO lcl_object. METHODS pass_by_value IMPORTING VALUE(io_object) TYPE REF TO lcl_object. ENDCLASS. CLASS lcl_example IMPLEMENTATION. METHOD constructor. ENDMETHOD. METHOD pass_by_reference. io_object->mv_color = 'green'. ENDMETHOD. METHOD pass_by_value. io_object->mv_color = 'blue'. CLEAR io_object. DATA(lo_object) = NEW lcl_object( ). lo_object->mv_color = 'yellow'. io_object = lo_object. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA(lo_example) = NEW lcl_example( ). DATA(lo_object) = NEW lcl_object( ). lo_object->mv_color = 'red'. WRITE: / lo_object->mv_color. lo_example->pass_by_reference( lo_object ). WRITE: / lo_object->mv_color. lo_example->pass_by_value( lo_object ). WRITE: / lo_object->mv_color.
Have a look at the method PASS_BY_REFERENCE. You cannot change the IMPORTING parameter itself. For example you cannot do a “CLEAR io_object “. But you can change the public attribute named MV_COLOR – even it’s an IMPORTING parameter passed by reference. It’s just the reference you cannot change but you can follow the reference to the object and manipulate that object.
Now have a look at the method PASS_BY_VALUE. You have access to the public attribute MV_COLOR and you can do a “CLEAR io_object”. It’s a local copy of the reference. Even more, you can create a new local object and move it to IO_OBJECT. All of this is possible
But not all is effective, however. If you run the example by F9 in Eclipse, the following color sequence is shown in console:
The explanation can be found in the ABAP help. See “pass by value” and “pass by reference” documentation. Another nice example with CHANGING parameters is show in this documentation.
Best regards, thanks for reading and please stay healthy
P.S.: Check our new “Virtual Wishing Well for Blogging“.
P.S.S.: Not tired of reading blogs? Read about this blog by Daniel Mieg.
Thanks for sharing! It was an unpleasant surprise for me when I found a while ago that in the subroutines it's totally possible to change the USING parameter. 🙂 I guess it's kind of a violation of "design by contract" though.
If you offer an opportunity, one day somebody will do it. Knowingly or unknowingly, it doesn't matter. The result counts and it's bad 🙁
That's one of the reasons why FORMs are obsolete. The other is that they don't have to be typed.
Well for me this is not new and I like it 🙂
To be honest I would love to get rid of the CHANGING and EXPORTING part of the method call as it is in other languages, where you pass the variables/objects by reference or by value and you return objects or types or nothing. Somehow it is simpler and more clear. At least for me.
In the meantime I can't even remember how I wrote methods in Java or C#. Too long ago 🙂 In ABAP at least, I now work a lot with the RETURNING parameter. Several EXPORTING parameters can often be converted to a RETURNING structure. I only use CHANGING parameters in exceptional cases where it's really appropriate. Ultimately, I try to stick to the recommendations from Clean ABAP.
I'm a big fan of RETURNING and functional method calls. Don't think I used CHANGING even once in my own methods.
You're better than me. Sometimes I have to admit to using it. In my defence, it's when modularising legacy code so it's not entirely me fault...
Java is by type and positional, with override. It's always pass by reference.
Can anyone tell me the de facto difference between EXPORTING and CHANGING when passing by reference?
Not a lot! I can just think of these ones: