ABAP_Freak->Show( ) Episode 2: Debating Hungarian Notation and Data References vs. Field Symbols

This morning I was joined by Rich Heilman as well as a lively crowd in the chat for the latest episode of the ABAP Freak Show. Today was a little bit of a different approach to the regular live stream.  Instead of a technology demo or live coding; today was all about debating two hotly contested topics in the ABAP development space:  Usage of Hungarian Notation and Data References vs. Field Symbols.  I don’t generally post a blog for each of the video or live stream sessions, but I thought I would make an exception this time in order to better share the related links and example source source code that we used in the video.

Of course if you missed the live stream, that’s no problem.  You can watch the replay at any time. Even if you couldn’t join the chat live; you can always add your thoughts to the comments on the video or here in this blog as well.

What would any healthy debate be without two opposing sides represented passionately. So in one corner we have Rich Heilman defending the usage of Hungarian Notation in ABAP. He makes the case that it allows looking at a glance to determine the type and scope of a variable and overall makes your code more readable without needing IDE features to assist. I took the opposite position that it clutters your code, that often the usage context can tell you as much about the object, the IDE can fill in the information more reliably, and that over time its too easy for naming to get out of sync with the reality.

And here was the simple ABAP class where we experimented with different usages with and without Hungarian Notation:

"! <p class="shorttext synchronized" lang="en">ABAP Class examples with and without Hungarian Notation</p> CLASS zcl_hungarian_notation DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun. methods mu_export_flights exporting !et_flights type /dmo/t_flight. methods get_flights exporting !flights type /dmo/t_flight. PROTECTED SECTION. PRIVATE SECTION. "! <p class="shorttext synchronized" lang="en">All Flights</p> DATA flights TYPE /dmo/t_flight. "! <p class="shorttext synchronized" lang="en">All Flights</p> data git_flights TYPE /dmo/t_flight. ENDCLASS. CLASS zcl_hungarian_notation IMPLEMENTATION. METHOD if_oo_adt_classrun~main. select * from /dmo/flight into table @flights. select * from /dmo/flight into table @git_flights. select * from @git_flights as FLIGHTS where carrier_id = 'AA' into table @data(lt_flights) . select * from @flights as FLIGHTS where carrier_id = 'AA' into table @data(flights_american). loop at lt_flights REFERENCE INTO data(lr_flight). if lr_flight->connection_id = '0017'. endif. endloop. loop at flights_american REFERENCE INTO data(flight). if flight->connection_id = '0017'. endif. endloop. mu_export_flights( IMPORTING et_flights = data(li_flights) ). get_flights( IMPORTING flights = data(processed_flights) ). ENDMETHOD. METHOD mu_export_flights. et_flights = git_flights. ENDMETHOD. METHOD get_flights. flights = me->flights. ENDMETHOD. ENDCLASS.

Of course we’d also recommend that everyone read up on the topic in the ABAP Clean Code Guidelines as well:

https://github.com/SAP/styleguides/blob/master/clean-abap/sub-sections/AvoidEncodings.md

Next up was a debate that might not be as contentious as the usage of Hungarian Notation, but one equally interesting:  Data References vs. Field Symbols.  This actually came up as a topic during the recent ABAP Code Challenge and we thought it would be good to visit it in detail.

This too has been debated in the ABAP Clean Code Guidelines.  In fact the main part of the debate seems to be the impact on performance.

https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#prefer-ref-to-to-field-symbol

https://github.com/SAP/styleguides/issues/115

I personally much prefer the consistency and object oriented type approach that data references provide.  I was honestly a little surprised to read that there might be a performance drawback to data references considering they are the newer, more modern syntax.  So on the live stream we set out to test this ourselves.

Here is the test class:

"! <p class="shorttext synchronized" lang="en">Field-Symbol vs. Reference Performance Testing</p> CLASS zcl_fs_ref_perf_testing DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun. PROTECTED SECTION. PRIVATE SECTION. DATA flights TYPE /dmo/t_flight. METHODS data_test. METHODS field_symbols_test. METHODS data_ref_test. ENDCLASS. CLASS zcl_fs_ref_perf_testing IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DO 1000 TIMES. SELECT * FROM /dmo/flight APPENDING TABLE @flights. ENDDO. data_test( ). field_symbols_test( ). data_ref_test( ). ENDMETHOD. METHOD data_test. LOOP AT flights INTO DATA(flight). IF flight-carrier_id = `SQ`. flight-price += 35. modify table flights from flight. ENDIF. ENDLOOP. ENDMETHOD. METHOD field_symbols_test. LOOP AT flights ASSIGNING FIELD-SYMBOL(<flight>). IF <flight>-carrier_id = `SQ`. <flight>-price += 35. ENDIF. ENDLOOP. ENDMETHOD. METHOD data_ref_test. LOOP AT flights REFERENCE INTO DATA(flight). IF flight->carrier_id = `AA`. flight->price += 35. ENDIF. ENDLOOP. ENDMETHOD. ENDCLASS.

And yes our testing did prove out the point that field-symbols are technically faster than data references; but the difference is so small that even in very large loop structures the difference probably isn’t all that noticeable. Still its good technical background to have on the topic.

Finally we did close out with one very special exception to the data references vs. field symbols debate: dynamically programming specifically with the assign component of structure approach.  Short of resulting to RTTI classes; I’m not aware of a real alternative to utilizing field symbols in this case. Feel free to offer suggestions if you have an alternative approach.  Therefore to every good guideline there remains valued exceptions.  Here is demo class to show the usage of the assign component syntax:

"! <p class="shorttext synchronized" lang="en">ABAP Inline Declaration</p> CLASS zcl_inline_declare DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun. PROTECTED SECTION. PRIVATE SECTION. METHODS old_way IMPORTING out TYPE REF TO if_oo_adt_classrun_out. METHODS new_way IMPORTING out TYPE REF TO if_oo_adt_classrun_out. ENDCLASS. CLASS zcl_inline_declare IMPLEMENTATION. METHOD if_oo_adt_classrun~main. old_way( out ). new_way( out ). ENDMETHOD. METHOD old_way. DO 10 TIMES. SELECT * FROM /dmo/flight APPENDING TABLE @DATA(flights). ENDDO. FIELD-SYMBOLS: <line1> LIKE LINE OF flights, <line> LIKE LINE OF flights, <comp> TYPE any. * READ TABLE flights ASSIGNING <line1> INDEX 1. LOOP AT flights ASSIGNING <line>. DO 3 TIMES. ASSIGN COMPONENT sy-index OF STRUCTURE <line> TO <comp>. out->write( <comp> ). ENDDO. ENDLOOP. ENDMETHOD. METHOD new_way. DO 10 TIMES. SELECT * FROM /dmo/flight APPENDING TABLE @DATA(flights). ENDDO. * READ TABLE flights REFERENCE INTO DATA(new_line1) INDEX 1. LOOP AT flights REFERENCE INTO DATA(new_line). DO 3 TIMES. ASSIGN COMPONENT sy-index OF STRUCTURE new_line->* TO FIELD-SYMBOL(<new_comp>). out->write( <new_comp> ). ENDDO. ENDLOOP. ENDMETHOD. ENDCLASS.