Skip to Content

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( … ).

  …

ENDIF.

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( ).

  cl_demo_output=>display(

     ‘This demo cannot be executed in a production system’ ).

  LEAVE PROGRAM.

ENDIF.

Here, a predicative method is called that returns ABAP_TRUE or ABAP_FALSE.

COND string( WHEN cl_demo_spfli=>get_spfli( to_upper( carrier ) )

               THEN `Filled`

               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’ ).
ELSE.
  cl_demo_output=>display_text( ‘no’ ).
ENDIF.

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’ ).

ELSE.

  cl_demo_output=>display_text( ‘no’ ).

ENDIF.

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.

To report this post you need to login first.

15 Comments

You must be Logged on to comment or reply to a post.

  1. Nigel James

    Can you please explain why ABAP cannot have a boolean type ?

    IF false.

      cl_demo_output=>display_text( ‘yes’ ).

    ELSE.

      cl_demo_output=>display_text( ‘no’ ).

    ENDIF.

    (0) 
    1. Horst Keller Post author

      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 πŸ™ .

      (0) 
      1. Jacques Nomssi

        Hello Horst,

        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?

        best regards,

        Jacques

        (0) 
        1. Horst Keller Post author

          Exactly this is currently under discussion.

          Something like

          IF ( value ).

          or maybe

          IF bool( value ).

          You cannot simply write  only a value because of IF seltab.

          Cheers!

          Horst

          (1) 
  2. Paul Hardy

    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?

    Cheersy Cheers

    Pul

    (0) 
    1. Horst Keller Post author

      Hi Paul,

      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.

      Horst

      (0) 
      1. Jānis B

        Hi,

        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 .

            CLASS-METHODS: get_instance

              RETURNING value(ro_test_boolc) TYPE REF TO lcl_test_boolc.

            METHODS: takeit

              IMPORTING value(if_boolc) TYPE c.

          PRIVATE SECTION .

            CLASS-DATA: so_instance TYPE REF TO lcl_test_boolc .

        ENDCLASS .

        CLASS lcl_test_boolc IMPLEMENTATION .

          METHOD get_instance .

            IF so_instance IS INITIAL .

              CREATE OBJECT so_instance .

            ENDIF .

            ro_test_boolc = so_instance .

          ENDMETHOD .

          METHOD takeit.

            BREAK-POINT .

            WRITE: / if_boolc.

            SET PARAMETER ID ‘TEST’ FIELD if_boolc .

          ENDMETHOD .

        ENDCLASS .

        START-OF-SELECTION .

          lcl_test_boolc=>get_instance( )>takeit(

            if_boolc = boolc( space IS NOT INITIAL )

          ).

        Edit in: Type XFELD takes it πŸ˜‰

        cheers

        Janis

        (0) 
        1. Paul Hardy

          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…..

          (0) 
          1. Jānis B

            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 πŸ™‚

            (0) 
        2. Horst Keller Post author

          compiler accepts boolc( ) as actual parameter to a formal parameter of type c

          That is a documented feature, of course πŸ˜‰

          • A string function or a string expression can
          • be bound to any character-like typed input parameter in a method call.

          and

          The return value of a function or the result of a calculation expression, a
          constructor expression, or a table expression is converted, if
          necessary, to the type of the input parameter and passed.

          That should explain the behavior discussed here …

          (0) 
    2. Christian Guenter

      Hi Paul,

      you can work around this problem with a predicate helper method which has a returning value of type abap_bool.

      Example:

      ….

      method: is_one_eq_two RETURNING value(r_one_eq_two) TYPE abap_bool.

      ….

      method is_one_eq_two.

           r_one_eq_two = BOOLC( 1 = 2 ).

      endmethod.

      if is_one_eq_two( ) = ABAP_FALSE.  “evaluates to true

      endif.

      Regards Christian

      (0) 

Leave a Reply