Skip to Content
Technical Articles

Determine the current class and method names in ABAP

In some situations, it can be useful to be able to determine the names of the current class and method dynamically instead of using hard-coded strings. I find this particularly useful for logging purposes. I have a helper class which writes to the system log when certain exceptions are triggered. As input to this helper class (or rather the method writing to the system log) I want to provide the names of the class and method where the exception was raised.

Determining the name of the current class

SAP provides the class CL_ABAP_CLASSDESCR for determining some class attributes dynamically. To determine the name of the current class, the following code snippet can be used:

DATA(lv_class_name) = cl_abap_classdescr=>get_class_name( me ).

LV_CLASS_NAME will contain the class name in the following format: \CLASS=ZCL_MY_CLASS

Determining the name of the current method

The only approach I’ve found for determining the name of the current method is by using a function module to read the call stack. If you are aware of a better way of doing this, please leave a comment! The call stack approach looks like this:

DATA lt_callstack TYPE abap_callstack.

CALL FUNCTION 'SYSTEM_CALLSTACK'
  EXPORTING
    max_level = 1
  IMPORTING
    callstack = lt_callstack.

DATA(lv_method_name) = lt_callstack[ 1 ]-blockname.

LV_METHOD_NAME will contain the method name in the following format: MY_METHOD

Happy coding!

This article first appeared on the Developer Voyage blog at https://www.developervoyage.com/2019/09/13/determine-the-current-class-and-method-names/

7 Comments
You must be Logged on to comment or reply to a post.
  • Surely the call stack method looks something like this

    CLASS zcl_utilities DEFINITION FINAL.
      PUBLIC SECTION.
        METHODS:
          this_method_name
            RETURNING
              VALUE(result) TYPE STRING.
    ENDCLASS.
    
    CLASS zcl_utilities IMPLEMENTATION.
      METHOD this_method_name.
        CONSTANTS c_previous_method_level TYPE i VALUE 2.
        DATA callstack TYPE abap_callstack.
        CALL FUNCTION 'SYSTEM_CALLSTACK'
            EXPORTING
              max_level = 1
            IMPORTING
              callstack = callstack.
        result = callstack[ c_previous_method_level ]-blockname.
      ENDMETHOD.
    ENDCLASS.
    
    
    CLASS ltc_utilities DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
      PRIVATE SECTION.
        DATA cut TYPE REF TO zcl_utilities.
        METHODS:
          setup,
          this_method_name.
    ENDCLASS.
    
    CLASS ltc_utilities IMPLEMENTATION.
      METHOD setup.
        cut = new #( ).
      ENDMETHOD.
      
      METHOD this_method_name.
        cl_abap_unit_assert=>assert_equals( exp = 'THIS_METHOD_NAME' act = cut->this_method_name( ) ).
      ENDMETHOD.
    ENDCLASS.

    I’ve not actually tried this yet. 😉

    • Thanks for your comment. There is one small change needed to make your code work. You need to adjust the max_level like this:

          CONSTANTS c_previous_method_level TYPE i VALUE 2.
          DATA callstack TYPE abap_callstack.
          CALL FUNCTION 'SYSTEM_CALLSTACK'
              EXPORTING
                max_level = c_previous_method_level
              IMPORTING
                callstack = callstack.

       

  • You could also use class CL_ABAP_GET_CALL_STACK (with the methods like GET_CALL_STACK( ) or FORMAT_CALL_STACK_WITH_STRUCT()) instead of the function module.

    Peter

    • Thanks for your suggestion. That is an interesting approach! So something like this:

          DATA(lt_formatted_stack) = cl_abap_get_call_stack=>format_call_stack_with_struct(
                                       cl_abap_get_call_stack=>get_call_stack( ) ).
          DATA(lv_method_name) = substring_after( val = lt_formatted_stack[ 1 ]-event sub = '=>' ).
      • Yes. Something like that 🙂

        And generally I try to avoid to table[ 1 ] when it’s not checked that it’s not initial, otherwise it dumps.

        For example:

          DATA(ld_last_event) = VALUE #( lt_formatted_stack[ 1 ]-event OPTIONAL ).
          IF ld_last_event IS NOT INITIAL.
            DATA(lv_method_name) = substring_after( val = ld_last_event sub = '=>' ).
          ENDIF.

         

        • I’d use

          ASSERT ld_last_event IS NOT INITIAL.

          because it should never not be initial.

          I’ve made my code robust(er) now. (And in accordance with DSUG and SAP Guideline, and the clean code project – no pesky typing prefixes… 😉 ).

          CLASS zcl_utilities DEFINITION FINAL.
            PUBLIC SECTION.
              METHODS:
                this_method_name
                  RETURNING
                    VALUE(result) TYPE STRING.
          ENDCLASS.
          
          CLASS zcl_utilities IMPLEMENTATION.
            METHOD this_method_name.
              CONSTANTS c_previous_method_level TYPE i VALUE 2.
              DATA callstack TYPE abap_callstack.
              CALL FUNCTION 'SYSTEM_CALLSTACK'
                  EXPORTING
                    max_level = c_previous_method_level
                  IMPORTING
                    callstack = callstack.
              ASSERT callstack IS NOT INITIAL.
              DATA(line_of_the_method) = SWITCH #( LINES( callstack ) WHEN 1 THEN 1
                                                                      ELSE 2 ).
              result = callstack[ line_of_the_method ]-blockname.
            ENDMETHOD.
          ENDCLASS.
          
          
          CLASS ltc_utilities DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
            PRIVATE SECTION.
              DATA cut TYPE REF TO zcl_utilities.
              METHODS:
                setup,
                this_method_name.
          ENDCLASS.
          
          CLASS ltc_utilities IMPLEMENTATION.
            METHOD setup.
              cut = new #( ).
            ENDMETHOD.
            
            METHOD this_method_name.
              cl_abap_unit_assert=>assert_equals( exp = 'THIS_METHOD_NAME' act = cut->this_method_name( ) ).
            ENDMETHOD.
          ENDCLASS.