‎2013 Nov 05 8:21 AM
I have some code in a public instance method. I discovered that the exporting parameter ex_is_negative, once set to TRUE stays TRUE when the method is called repeatedly in a loop:
Is this expected behavior? By default, I would have expected that the variable, being an export variable, should be initialized each time the method enters, but obviously this is not the case.
Do people consider this a bug or normal behavior? Maybe failing to initialize all export parameter variables is not good practice, but languages such as Java would not allow this to happen.
‎2013 Nov 05 9:12 AM
It is not what I would expect ... but it is what happens. I have encountered this as well. Exporting parameters seem to be behaving exactly like changing parameters.
I think it is a bug. However it is documented
"An output parameter that is defined for the reference transfer is not initialized when the method is called. Therefore, no read access to it should take place before the first write access. "
To those who think it doesn't work like this, try this program:
REPORT.
TYPE-POOLS: abap.
*----------------------------------------------------------------------*
* CLASS test DEFINITION
*----------------------------------------------------------------------*
CLASS test DEFINITION.
PUBLIC SECTION.
METHODS truefalse EXPORTING flag TYPE abap_bool.
ENDCLASS. "test DEFINITION
*----------------------------------------------------------------------*
* CLASS test IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS test IMPLEMENTATION.
METHOD truefalse.
WRITE: / 'Value of flag at start', flag.
IF flag EQ abap_false.
flag = abap_true.
ENDIF.
ENDMETHOD. "truefalse
ENDCLASS. "test IMPLEMENTATION
END-OF-SELECTION.
DATA: test TYPE REF TO test.
CREATE OBJECT test.
DATA: flag TYPE abap_bool.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
flag = abap_false.
SKIP.
WRITE: / 'Flag set to false'.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
flag = 'F'.
SKIP.
WRITE: / 'Flag set to F'.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
‎2013 Nov 05 8:38 AM
Hi,
this is an Exporting or a Changing parameter ?
I will be surprise for exporting, not surprise for changing.
regards
Fred
‎2013 Nov 05 8:46 AM
Hi,
It's an exporting parameter; that's why I didn't initialize it; I assumed it would be initialized each time the method is entered.
‎2013 Nov 05 8:54 AM
Hi Anthony
Can you please share with us the screen shot of the parameter declaration
Thanks
Nabehet
‎2013 Nov 05 8:55 AM
It will automatically be initialized each time the method is called.
Can you share the code for definition, implementation and object creation with call to method?
‎2013 Nov 05 9:48 AM
Hi,
Here's the method signature:
Definition of object:
Call to method in loop:
‎2013 Nov 05 10:06 AM
Hi Anthony,
You will need to add the code to export value for both cases.
if ls_t156-shkzg = c_debit.
ex_is_negative = c_true.
else.
ex_is_negative = c_false.
endif.
‎2013 Nov 05 10:12 AM
Hi,
Yes I did that already thanks 🙂 This is really to follow up WHY the language has been designed to behave that way...
‎2013 Nov 05 9:12 AM
It is not what I would expect ... but it is what happens. I have encountered this as well. Exporting parameters seem to be behaving exactly like changing parameters.
I think it is a bug. However it is documented
"An output parameter that is defined for the reference transfer is not initialized when the method is called. Therefore, no read access to it should take place before the first write access. "
To those who think it doesn't work like this, try this program:
REPORT.
TYPE-POOLS: abap.
*----------------------------------------------------------------------*
* CLASS test DEFINITION
*----------------------------------------------------------------------*
CLASS test DEFINITION.
PUBLIC SECTION.
METHODS truefalse EXPORTING flag TYPE abap_bool.
ENDCLASS. "test DEFINITION
*----------------------------------------------------------------------*
* CLASS test IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS test IMPLEMENTATION.
METHOD truefalse.
WRITE: / 'Value of flag at start', flag.
IF flag EQ abap_false.
flag = abap_true.
ENDIF.
ENDMETHOD. "truefalse
ENDCLASS. "test IMPLEMENTATION
END-OF-SELECTION.
DATA: test TYPE REF TO test.
CREATE OBJECT test.
DATA: flag TYPE abap_bool.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
flag = abap_false.
SKIP.
WRITE: / 'Flag set to false'.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
flag = 'F'.
SKIP.
WRITE: / 'Flag set to F'.
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
test->truefalse( IMPORTING flag = flag ).
‎2013 Nov 05 9:57 AM
There you have it - thanks! I don't agree with this; it means that I need to explicitly initialize exporting parameters from now on. My failing to read the small print was the root cause .
Do you think that is bad language design, or is there a good reason for that behavior, do you think?
‎2013 Nov 05 10:06 AM
I think it is conceptually incorrect. I can't think of a good reason.
‎2013 Nov 05 10:10 AM
Definitely it does not sound logical, that values are passed to the method through exporting parameters. For that we have importing and changing parameters. Flow of information should be unidirectional for importing and exporting parameters.
However, on a positive note, Anthony, you don't have to initialize the parameter each time you use the method, since you are not reading directly from this parameter in the method. You just need to make sure both cases are handled in your method. Refer the code I have given above.