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?
Exception cx_langu_not_supported is not defined in the signature of meth( ) 😕
How to handle it then?
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.
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.....
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 ...
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)
Latest versions of SAP GUI and ADT Editors do it right.
Hello Horst,
I am not able to specify an object reference type as a result to COND/SWITCH directly. I can write:
where LIF_OUTPUT is an interface implemented by the 3 classes, but what I really want is to write
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):
Can this be improved? (I am testing on 7.50 SP02). Did I missed some documentation?
best regards,
JNN
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.