Application Development 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: 

Smartest way for equivalent of VALUE #( LET aux = ... IN value_using_aux ) - Subjective

Sandra_Rossi
Active Contributor

The ABAP language doesn't allow to use LET ... IN with the first variant of the VALUE construction operator, named "Initial value for all types".

I'd like to use an alternative of LET ... IN with the first variant, to avoid declaring a local variable. I want to use auxiliary variables or method calls as far as possible instead.

It's possible to use VALUE #( LET ... IN ... ) only with the two other variants for constructing a structure component by component or a table, as shown in the ABAP Keyword documentation - VALUE, Value Operator:

  • Pass by parameter when constructing values:
  • 1. Initial value for all types
  • 2. Structures
  • 3. Internal tables
1. Initial value for all types: (including single fields)
-------------------------------

... VALUE dtype|#( ) ...

2. Structures:
--------------

... VALUE dtype|#( [let_exp] 
                   [BASE dobj] 
                   comp1 = dobj1 comp2 = dobj2 ... ) ...

3. Internal tables:
-------------------

... VALUE dtype|#( [let_exp] 
                   [BASE itab] 
                   [FOR for_exp1 
                    FOR for_exp2 
                    ... ] 
                   ( line_spec1 ) 
                   ( line_spec2 ) 
                     ... ) ... 

Allowing LET with the first variant would be ideal in probably many situations.

For example, in the code below, the ACT parameter is filled with the MID component, but I feel there's a legibility issue, MID is almost invisible:

cl_abap_unit_assert=>assert_equals(
    act = lth_abap_code=>syntax_check( VALUE #( ( `REPORT.                                     ` )
                                                ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                                ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                                ( `ref_to_abap_bool = ref_to_data.             ` ) )
          )-mid
    exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).
I'd like to highlight MID by using what would be ideal (to me) but is an invalid syntax as I said:
    cl_abap_unit_assert=>assert_equals(
        act = VALUE trmsg_key( LET sc_result = lth_abap_code=>syntax_check(
                                    VALUE #( ( `REPORT.                                     ` )
                                             ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                             ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                             ( `ref_to_abap_bool = ref_to_data.             ` ) ) )
                               IN mid = sc_result-mid )
        exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).

I have the workarounds below.

And you: which workaround or other possibility do you use to mimic the first variant with LET?

Thank you!

Sandra

---------------------------------------------

My workarounds:

  1. Local variable instead of inline construction. I want to avoid local variables which are used once.
  2. New method. Well, creating a method for each auxiliary variable is too much. But fine if the method is called at several places.
  3. Using the second variant (structure), if possible.
  4. Faking with COND always true

Corresponding codes:

1. Local variable instead of inline construction
------------------------------------------------

DATA(sc_result) = lth_abap_code=>syntax_check(
                                    VALUE #( ( `REPORT.                                     ` )
                                             ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                             ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                             ( `ref_to_abap_bool = ref_to_data.             ` ) ) ).
cl_abap_unit_assert=>assert_equals(
    act = sc_result-mid
    exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).


2. New method
------------------

cl_abap_unit_assert=>assert_equals(
    act = get_message_of_syntax_check( VALUE #( ( `REPORT.                                     ` )
                                                ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                                ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                                ( `ref_to_abap_bool = ref_to_data.             ` ) )
    exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).


3. Using the second variant (structure)
---------------------------------------

cl_abap_unit_assert=>assert_equals(
    act = VALUE lth_abap_code=>ty_syntax_check( LET sc_result = lth_abap_code=>syntax_check(
                                   VALUE #( ( `REPORT.                                     ` )
                                            ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                            ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                            ( `ref_to_abap_bool = ref_to_data.             ` ) ) )
          IN mid = sc_result-mid )
    exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).


4. Faking with COND always true
-------------------------------

cl_abap_unit_assert=>assert_equals(
    act = COND trmsg_key( WHEN 1 = 1
                              THEN LET sc_result_2 = lth_abap_code=>syntax_check(
                       VALUE #( ( `REPORT.                                     ` )
                                ( `DATA ref_to_data      TYPE REF TO data.     ` )
                                ( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
                                ( `ref_to_abap_bool = ref_to_data.             ` ) ) )
                        IN sc_result_2-mid )
        exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).
2 REPLIES 2

ChristianGünter
Contributor

Hello Sandra,

what about using CONV instead of VALUE?

    cl_abap_unit_assert=>assert_equals(
act = CONV trmsg_key(
LET sc_result = lth_abap_code=>syntax_check(
VALUE #( ( `REPORT. ` )
( `DATA ref_to_data TYPE REF TO data. ` )
( `DATA ref_to_abap_bool TYPE REF TO abap_bool.` )
( `ref_to_abap_bool = ref_to_data. ` ) ) )
IN sc_result-mid )
exp = VALUE trmsg_key( spras = sy-langu keyword = 'MESSAGE' msgnumber = 'GXD' ) ).


BR Christian

Oooh, you are killing me, so simple 😄

I guess I have to add a pragma to say that the "fake conversion" is done on purpose.

Let me check tomorrow, but it's the best one from far.