ABAP News for 7.40, SP08 – Logical Expressions
Predicative Method Calls
For quite some time the lack of a real boolean type in ABAP led to a lot of discussions inside and outside of SAP and especially in SCN. People kept asking, why can I not write
IF meth( … ).
The answer always was: Because you have to have a boolean type behind IF and no method can return a boolean type.
But in fact, the solution was absolutely simple and – tatarata! – is made availabe in Release 7.40, SP08.
You can write the so called predicative method call
… meth( ) …
as a short form of the relational expression
… meth( ) IS NOT INITIAL …
now and that’s already all! Of course, methods that return a value of type ABAP_BOOL are especially suited for that purpose. We call those predicate methods now, but it’s not a prerequisite to use them.
So you can place simple functional method calls everywhere, where logical expressions are allowed: behind IF, CHECK, ASSERT, COND, SWITCH, …
The documentation shows some examples:
IF cl_abap_demo_services=>is_production_system( ).
‘This demo cannot be executed in a production system’ ).
Here, a predicative method is called that returns ABAP_TRUE or ABAP_FALSE.
COND string( WHEN cl_demo_spfli=>get_spfli( to_upper( carrier ) )
ELSE `Not filled` )
Here, a normal method is called and the result is true, if the table type return value contains lines.
Why didn’t we enable this long before?
New Boolean Function
Did you ever stumble over that one?
IF boolc( 1 = 2 ) = abap_false.
cl_demo_output=>display_text( ‘yes’ ).
cl_demo_output=>display_text( ‘no’ ).
The relational expression boolc( 1 = 2 ) = abap_false is false! Why? Because boolc despite its name does not return c but string and the comparison rules for c and string blah, blah, blah …
Now, with Release 7.40, SP08, we have an new Boolean function.
IF xsdbool( 1 = 2 ) = abap_false.
cl_demo_output=>display_text( ‘yes’ ).
cl_demo_output=>display_text( ‘no’ ).
The relational expression xsdbool( 1 = 2 ) = abap_false is true, because xsdbool returns type XSDBOOLEAN from the ABAP Dictionary that is – yes, you guess it – c of length 1. For the experts among you, XSDBOOLEAN is normally used for special mappings in XML-transformations and was reused here for quite another purpose. And that’s were the funny name xsdbool comes from.
The new Boolean function xsdbool can be used everywhere, where comparisons with type c length 1 are needed, especially comparisons with type ABAP_BOOL.But be aware of the fact, that the space that is returned by xsdbool for a false expression is cut in many operand positions, e.g. if you want to convert it with a builtin function like translate.
xsdbool is xsdcool 😆
Can you please explain why ABAP cannot have a boolean type ?
cl_demo_output=>display_text( 'yes' ).
cl_demo_output=>display_text( 'no' ).
Historical reasons. When ABAP was created, nobody cared and now it is too late. No way to introduce a new boolean data type with a meaningful name in a downward compatible way 🙁 .
why is this predicative logic is limited to functional method calls? Shouldn't it be possible to define any NOT INITIAL value as a logical TRUE in a logical expression position without downward compatibility problem?
Exactly this is currently under discussion.
IF ( value ).
IF bool( value ).
You cannot simply write only a value because of IF seltab.
I can't imagine dealing with all that backwards compatibility...the folks working on the ABAP compiler are heroes.
I had been using BOOLC all over the place and so was horrified that IF BOOLC( 1 = 2 ) = ABAP_FALSE would not be FALSE.
I tried it in my system and BOOLC( 1 = 2) evaluated to FALSE which is the opposite behaviour to that which you describe above.
I am on ECC 6.0 EHP5. Support stack 702 BASIS 13.
Has the BOOLC problem been resolved via a support stack?
BOOLC( 1 = 2) evaluates to a string containing a blank of length 1. So far so good. But comparing ` ` with ' ' or ABAP_FALSE is false, since the text field is converted to string resulting in an empty string. I bet that's the same on your system. And that's the trap. You simply cannot compare BOOLC( 1 = 2) with ABAP_FALSE, only with ABAP_TRUE.
don't know if it's mentioned already somwhere, but on 702 SAPKB70211 compiler accepts boolc( ) as actual parameter to a formal parameter of type c, which results in case of false boolc( ) result in unassigned parameter:
CLASS lcl_test_boolc DEFINITION CREATE PRIVATE.
PUBLIC SECTION .
RETURNING value(ro_test_boolc) TYPE REF TO lcl_test_boolc.
IMPORTING value(if_boolc) TYPE c.
PRIVATE SECTION .
CLASS-DATA: so_instance TYPE REF TO lcl_test_boolc .
CLASS lcl_test_boolc IMPLEMENTATION .
METHOD get_instance .
IF so_instance IS INITIAL .
CREATE OBJECT so_instance .
ro_test_boolc = so_instance .
WRITE: / if_boolc.
SET PARAMETER ID 'TEST' FIELD if_boolc .
if_boolc = boolc( space IS NOT INITIAL )
Edit in: Type XFELD takes it 😉
I tested that in my system, and passed in
IF_BOOLC = ( 1 = 2 ).
The result was ABAP_FALSE.
In my geeric method for seeing if things are true I pass in the result of BOOLC and my importing parameter was ABAP_BOOL wich is type C length 1 so I am laughing.
So that is quite a handy tip.....
I had some inexplicable "doubts" about boolc and only started using it couple of days ago as a handy way of inverting the booleans, where necessary, while passing them in to a routine to write out to user master SET/GET parameters. That routine had c type, since I couldn't figure out if there is a lasting agreement about the right length of the values those can take... Now my "paranoia" meter will be peaking 🙂
That is a documented feature, of course 😉
That should explain the behavior discussed here ...
you can work around this problem with a predicate helper method which has a returning value of type abap_bool.
method: is_one_eq_two RETURNING value(r_one_eq_two) TYPE abap_bool.
r_one_eq_two = BOOLC( 1 = 2 ).
if is_one_eq_two( ) = ABAP_FALSE. "evaluates to true
As of Release 7.40 less expensive with
IF CONV abap_bool( boolc( 1 = 2 ) ) = abap_false.
and less readable 😉
Why does this not work?
If force were a method returning boolean it would work so why not for a literal?
Unfortunately this syntax is prohibited by an obsolete variant.
Got another puzzle for you Horst which doesn't work though I would expect it to:
Also, I always believed '-' is false in a BOOLEAN (as the data element description says) but I recently read '-' is "undefined" and '' is the true false. Which is it?
You want to use a host expression in Open SQL, but you use the wrong syntax. Host expressions are available with 7.50 and must be placed in brackets @( ). See the documentation.
We don’t have real booleans in ABAP. There are a lot of different frameworks definining their own artificial booleans and those might differ.
The docu doesn’t cover this case. It shows this working:
But an inline version does not compile:
What is your release?
Pfff. ABAP is getting uglier and uglier. Why pumping up that clean and straight language with tons of new statements that only developers missed that come from other languages to ABAB? Result: Destroying readness instead of simplifing it.
Look at the examples in package SABAP_DEMOS_STRING_PROCESSING.
Well.. Thx for your answer, but it doesn't make me happy. I read the examples with interest. As you can see with that examples: The result ist always the same (writing a html-file). I am able to read quickly the 7.0 example, for the 7.4 example i need one hour to watch out and understand the new way of writing the same result. Using more and more implicit way of expressing, more and more brackets/symbols like ( } | &, more and more ways of expressing the same in another way. For me it doesnt increase readability. It just increases complexity of the language. I'am an old ABAP dinosaur... and not a fan of function-oriented languages. But thats the trendy line, i will adopt that.