Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

[ABAP-OO] Recursive Code not working (Bug ?)

Former Member
0 Likes
2,464

Hi Experts,

I have a really simple recursive code in that way:

But, when I execute it in debug mode, the program is working well.

  • the CASE 01 is call and the recursive method is executed, then
  • the CASE 02 is call and the recursive method is executed then,
  • the CASE 05 is call and the recursive method is executed then,
  • ect....
  • the CASE 19 is call and exit.

But without the debug mode (in real mode), my program does not work, the behavior is really strange:

  • "The program at the CASE 01 (line 9) go to the CASE 02 (linee 12) and EXIT..."

Is it a bug ? because in Debug Mode, step by step, it's working well ...


Have you got some idea ?

Many thanks.

Rachid.

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
2,363

Hi, and Jörg ,

thank you very much.

To avoid a maximum of misunderstanding, I have made a short vidéo concerning my issue with a debug mode displayed in 2 ways:

  • F5 => STEP by STEP
  • F6 => Execute Method

Thank again.

Rachid.

9 REPLIES 9
Read only

jrg_wulf
Active Contributor
0 Likes
2,363

Hi Rachid,

you really leave us with a lot of guesswork here. So it's only more questions and no answer (yet).

you wrote,  that after step02, the programm processes step05 - is that correct AND intended?

How do you know the program endet in line 12?

Why do you call steps 02 to 19 static, whereas step02 is computed?

Do you have any additional exit-conditions?

As far as i can see, the recursion is only a wrapper for the "case step". Beneath that, you have a different process-logic for each step? (process_step01, process_step02 ...)

I seem to miss the benefit of the recursion here. Couldn't you just DO .. ENDDO with the case inside?

Best regards - Jörg

Read only

nomssi
Active Contributor
0 Likes
2,363

Hello Rachid,

from your screenshot, it seems your table is passed by reference. That make it difficult to reason about.

I would propose to record an ABAP Trace without aggregation, then analyze the Call Hierarchy (or generate an UML sequence diagram).

hope this helps,

JNN

Read only

Former Member
0 Likes
2,364

Hi, and Jörg ,

thank you very much.

To avoid a maximum of misunderstanding, I have made a short vidéo concerning my issue with a debug mode displayed in 2 ways:

  • F5 => STEP by STEP
  • F6 => Execute Method

Thank again.

Rachid.

Read only

0 Likes
2,363

I re-coded and simplified the recursive method in a Test Class, in less than 5 minutes and I have the same behavior when I run my class in Local Test.

In F5 (step by step), my code is working well.

When F6, my code, is not executed correctly.

F8, local test:

The recursive is not respected...

I despair...

Rachid.

Read only

0 Likes
2,363

Hello Rachid,

I am currently not able to watch your video, however can you define what you mean by recursive is not respected?

WRITE statements inside a class will never give you an output when testing the class.

For me everything works as expected, check this out:


*&---------------------------------------------------------------------*
*& Report  ZTEMP_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ztemp_test.

*----------------------------------------------------------------------*
*       class lcl_class definition
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_class DEFINITION.
   PUBLIC SECTION.
     METHODS: add IMPORTING i TYPE i.

ENDCLASS.                    "lcl_class DEFINITION
*----------------------------------------------------------------------*
*       class lcl_class implementation
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_class IMPLEMENTATION.
   METHOD add.
     DATA l TYPE i.

     if i < 9.
       WRITE i.
       l = i + 1.
       me->add( l ).
     else.
       write i.
     endif.

   ENDMETHOD.                    "add
ENDCLASS.                  "lcl_class IMPLEMENTATION

START-OF-SELECTION.
   DATA obj TYPE REF TO lcl_class.

   CREATE OBJECT obj.
   CALL METHOD obj->add( 1 ).

Output is 1 through 9.

Read only

0 Likes
2,363

Thank you Dominik,

could you explain me why my last value from the recursive method is wrong?


*----------------------------------------------------------------------*

*       class lcl_class definition

*----------------------------------------------------------------------*

*

*----------------------------------------------------------------------*

CLASS lcl_class DEFINITION.

   PUBLIC SECTION.

     METHODS: add  IMPORTING i           TYPE i

                   RETURNING value(OUTtype i.

ENDCLASS.                    "lcl_class DEFINITION

*----------------------------------------------------------------------*

*       class lcl_class implementation

*----------------------------------------------------------------------*

*

*----------------------------------------------------------------------*

CLASS lcl_class IMPLEMENTATION.

   METHOD add.

     DATA l TYPE i.

     CASE i.

       WHEN 1.

         WRITE : 'recursive:', i.

         out = i.

         me->add( 2 ).

       WHEN 2.

         WRITE :/ 'recursive:', i.

         out = i.

         me->add( 3 ).

       WHEN 3.

         WRITE :/ 'recursive:', i.

         out = i.

         me->add( 4 ).

       WHEN 4.

         WRITE :/ 'recursive:', i.

         out = i.

         me->add( 5 ).

       WHEN 5.

         WRITE :/ 'recursive:', i.

         out = i.

         me->add( 6 ).

       WHEN OTHERS.

          out = i.

          WRITE :/ 'Last value of CASE(WHEN Others):', i.

     ENDCASE.

   ENDMETHOD.                    "add

ENDCLASS.                  "lcl_class IMPLEMENTATION

START-OF-SELECTION.

   DATA obj TYPE REF TO lcl_class.

   data out TYPE i.

   CREATE OBJECT obj.

   out  = obj->add( 1 ).

   WRITE :/ 'Last: out  = obj->add', out.

Normaly, out from  obj->add( ) must be the last value passed in the recursive method, so 6.

I don't understand why the program is doing a reverse path execution....

Rachid.

Read only

0 Likes
2,363

Well cause you are only returning the out value from the first add call. Here the corrected version:


*&---------------------------------------------------------------------*
*& Report  ZTEMP_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ztemp_test.

*----------------------------------------------------------------------*
*       class lcl_class definition
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
     CLASS lcl_class DEFINITION.
        PUBLIC SECTION.
          METHODS: add  IMPORTING i           TYPE i
                        RETURNING value(OUTtype i.

     ENDCLASS.                    "lcl_class DEFINITION

*----------------------------------------------------------------------*
*       class lcl_class implementation
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
     CLASS lcl_class IMPLEMENTATION.
        METHOD add.
          DATA l TYPE i.

          CASE i.
            WHEN 1.
              WRITE : 'recursive:', i.
              out = me->add( 2 ).

            WHEN 2.
              WRITE :/ 'recursive:', i.
              out = me->add( 3 ).

            WHEN 3.
              WRITE :/ 'recursive:', i.
              out = me->add( 4 ).

            WHEN 4.
              WRITE :/ 'recursive:', i.
              out = me->add( 5 ).

            WHEN 5.
              WRITE :/ 'recursive:', i.
              out = me->add( 6 ).

            WHEN OTHERS.
              WRITE :/ 'Last value of CASE(WHEN Others):', i.
              out = 6.

          ENDCASE.
        ENDMETHOD.                    "add
     ENDCLASS.                  "lcl_class IMPLEMENTATION

     START-OF-SELECTION.
        DATA obj TYPE REF TO lcl_class.
        data out TYPE i.
        CREATE OBJECT obj.
        out  = obj->add( 1 ).

        WRITE :/ 'Last: out  = obj->add', out.

Read only

0 Likes
2,363

Waw ! I did not notice that !

Thank you very much Dominik.

Well to sum up, we have a bug in the debug mode displayer for the F6 execution mode for recursive method.

And for the last point, you have totally reason ! Thank you very much again for this useful help !

Read only

0 Likes
2,363

Hello Rachid,

since your logic looks like:

the output parameter will not be defined until after the last recursion step. Does this explain the quirk with the debugger output?

You might consider helper methods to make your code look more like a simple recursive method, e.g.


METHOD process_recursive_steps( table = table

                                step = step ).

  CHECK step NE step_none.

  process_recursive_steps(

     table = process_step( table = table

                                             step = step )

     step = get_next_step_from( table = table

                                                        step = step ) ).

ENDMETHOD.

best regards,

JNN