Skip to Content
Author's profile photo Horst Keller

ABAP News for Release 7.40 – Constructor Operators COND and SWITCH

With Release 7.40 ABAP supports so called constructor operators. Constructor operators are used in constructor expressions to create a result that can be used at operand positions. The syntax for constructor expressions is

… operator type( … ) …

operator is a constructor operator. type is either the explicit name of a data type or the character #. With # the data type can be dreived from the operand position if the operand type is statically known. Inside the parentheses specific parameters can be specified.

Conditional operators COND and SWITCH

Last but not least, two nice ones, the conditionals COND and SWITCH.

  • … COND dtype|#( WHEN log_exp1 THEN result1
                    [ WHEN log_exp2 THEN result2 ]
                    …
                    [ ELSE resultn ] ) …

       constructs a result of the specified type that depends on logical expressions.

  • … SWITCH dtype|#( operand
                        WHEN const1 THEN result1
                      [ WHEN const2 THEN result2 ]
                      …
                      [ ELSE resultn ] ) …

constructs a result of the specified type that depends on a case differentiation.

With other words: IF and CASE as expressions in operand positions!

         

Example for COND

DATA(time) =

  COND string(

    WHEN sy-timlo < ‘120000’ THEN

      |{ sy-timlo TIME = ISO } AM|

    WHEN sy-timlo > ‘120000’ THEN

      |{ CONV t( sy-timlo – 12 * 3600 )

         TIME = ISO } PM|

    WHEN sy-timlo = ‘120000’ THEN

      |High Noon|

    ELSE

      THROW cx_cant_be( ) ).

Note the THROW. Now you can raise and  throw exceptions …

Example for SWITCH

CLASS cx_langu_not_supported DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.

CLASS class DEFINITION.
  PUBLIC SECTION.
    METHODS meth IMPORTING iso_langu   TYPE string
                 RETURNING VALUE(text) TYPE string.
ENDCLASS.

CLASS class IMPLEMENTATION.
  METHOD meth.
    …
  ENDMETHOD.
ENDCLASS.

  DATA(text) =
    NEW class(
      )->meth(
          SWITCH #( sy-langu
                    WHEN ‘D’ THEN `DE`
                    WHEN ‘E’ THEN `EN`
                    ELSE THROW cx_langu_not_supported( ) ) ).

Amazing, n’est-ce pas?

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Exception cx_langu_not_supported is not defined in the signature of meth( ) 😕

      How to handle it then?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      The exception is not thrown inside meth but in the context where meth is called. This context must have a raising clause which is not shown here.

      Author's profile photo Paul Hardy
      Paul Hardy

      While we are talking about local classes and methods, are there any plans in 740 or beyond, that when you re writing your code and call a method of a class and it does not exists, you get the "method does not exists - do you want to create it?" and it creates a skeleton implementation and defintion, which is the case for PERFORM routines.

      This would speed up test driven development enormously. Sometimes people wonder why programmers are slow to adopt OO, it is little niggly things like this that make writing methods more work than form routines. People are lazy so they take the easy option.

      I was told this is possible in ABAP in Eclipse.....

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      No support for this in SAP GUI but in (at least my) Eclipse, crtl+F1 on class=>meth( ) and it will create the method for you.

      Nevertheless, from my learning of ABAP long time ago I remember some very misleading effects from this. In old ABAP trainings they've explained subroutines (FORMs) coming from PERFORM. First write PERFORM. double click, implement. Problem was that people did not understand that the FORM and its parameter interface are the important part and that PERFORM is only its user. There were big problems in explaining the modes forparameter  passing because everything was based on PERFORM and not on FORM where the real definition lies. But let's expect, that nowadays developers know what they are doing ...

      Author's profile photo Former Member
      Former Member

      The COND has been very useful as a sort of ternary operator to streamline code that would otherwise look very convoluted.

      Sadly, it seems that the editor's syntax highlighting has not been updated for this notation and it will mark parts of the statement in red, indicating they are invalid even though it compiles and executes fine. Are there plans to update the syntax highlighter to support these statements? (Tested in 7.4 SP7 and SP9)

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Latest versions of SAP GUI and ADT Editors do it right.

      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Hello Horst,

      I am not able to specify an object reference type as a result to COND/SWITCH directly. I can write:

      METHODS output IMPORTING iv_ucomm       TYPE syucomm
                     RETURNING VALUE(rv_flag) TYPE flag.
      METHOD output.
        DATA li_export TYPE REF TO lif_output.
      
        li_export = SWITCH #( iv_ucomm WHEN 'FC01' THEN NEW lcl_plantuml_output( )
                                       WHEN 'ONLI' THEN NEW lcl_xmi_output( )
                                       ELSE NEW lcl_null_output( ) ).
        rv_flag = li_export->output( NEW lcl_parameter( ) ).
      ENDMETHOD.

      where LIF_OUTPUT is an interface implemented by the 3 classes, but what I really want is to write

        rv_flag = SWITCH lif_output( iv_ucomm 
          WHEN 'FC01' THEN NEW lcl_plantuml_output( )
          WHEN 'ONLI' THEN NEW lcl_xmi_output( )
          ELSE NEW lcl_null_output( )   )->output( NEW lcl_parameter( ) ).  

      but this triggers the error "object type LIF_OUTPUT can only be referenced using "REF TO". However, the following is valid (but I have to cast twice for type inference):

      rv_flag = CAST lif_output( SWITCH #( iv_ucomm
            WHEN 'FC01' THEN CAST lif_output( NEW lcl_plantuml_output( ) )
            WHEN 'ONLI' THEN NEW lcl_xmi_output( )
            ELSE NEW lcl_null_output( ) ) )->output( NEW lcl_parameter( ) ).

      Can this be improved? (I am testing on 7.50 SP02). Did I missed some documentation?

      best regards,

      JNN

       

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hello Jacques,

      What you are trying to do is a chaining with constructor operator SWITCH:

      … = SWITCH ref_type( … )->meth( ).

      This is not allowed and not documented. Only “Expressions with the operators NEW and CAST can be positioned directly before the object component selector -> and can occur in chainings.”

      As far as I know, there are no immediate plans for allowing chainnings for arbitrary constructor operators.

      Kind regards

      Horst

      PS:

      SWITCH #( WHEN ref1 IS BOUND THEN ref1->meth( ) ELSE ref2->meth( ) )

      is preferable to

      SWITCH reftype( WHEN ref1 IS BOUND THEN ref1 ELSE ref2 )->meth( )

      because of obfuscation.