Skip to Content

This one is a tribute to the community, to SCN, to you. One of you, Volker Wegert; has blogged his ABAP Wishlist – IS INSTANCE OF some years ago and reminded us again and again. Others backed him and I myself participated a little bit by forwarding the wish to the kernel developers. And constant dripping wears the stone, ABAP 7.50 comes with a new relational expression IS INSTANCE OF, even literally.

If you wanted to find out whether a reference variable of a given static type can point to an object before ABAP 7.50, you had to TRY a casting operation that might look like something as follows:


    DATA(typedescr) = cl_abap_typedescr=>describe_by_data( param ).

    DATA:
      elemdescr   TYPE REF TO cl_abap_elemdescr,
      structdescr TYPE REF TO cl_abap_structdescr,
      tabledescr  TYPE REF TO cl_abap_tabledescr.
    TRY.
        elemdescr ?= typedescr.
        …
      CATCH cx_sy_move_cast_error.
        TRY.
            structdescr ?= typedescr.
            …
          CATCH cx_sy_move_cast_error.
            TRY.

                tabledescr ?= typedescr.
                …
              CATCH cx_sy_move_cast_error.
                …
            ENDTRY.
        ENDTRY.
    ENDTRY.


In this example we try to find the resulting type of an RTTI-operation.

With ABAP 7.50 you can do the same as follows:

    DATA(typedescr) = cl_abap_typedescr=>describe_by_data( param ).
   

    IF typedescr IS INSTANCE OF cl_abap_elemdescr.
      DATA(elemdescr) = CAST cl_abap_elemdescr( typedescr ).
      …
    ELSEIF typedescr IS INSTANCE OF cl_abap_structdescr.
      DATA(structdescr) = CAST cl_abap_structdescr( typedescr ).
      …
    ELSEIF typedescr IS INSTANCE OF cl_abap_tabledescr.
      DATA(tabledescr) = CAST cl_abap_tabledescr( typedescr ).
      …
    ELSE.
      …
    ENDIF.

The new predicate expression IS INSTANCE OF checks, if the dynamic type of the LHS operand is more special or equal to an RHS type. In fact it checks whether the operand can be down casted with that type. In the above example, such a casting takes place after IF, but its your decision if you need it. If you need it, there is even a shorter way to write it. A new variant of the CASE -WHEN construct:!


    DATA(typedescr) = cl_abap_typedescr=>describe_by_data( param ).

    CASE TYPE OF typedescr.
      WHEN TYPE cl_abap_elemdescr INTO DATA(elemdescr).
        …
      WHEN TYPE cl_abap_structdescr INTO DATA(structdescr).
        …
      WHEN TYPE cl_abap_tabledescr INTO DATA(tabledescr).
        …
      WHEN OTHERS.
        …
    ENDCASE.

The new TYPE OF and TYPE additions to CASE and WHEN allow you to write IS INSTANCE OF as a case control structure. The optional INTO addition does the casting for you, I think that’s rather cool.

B.T.W., the new IS INSTANCE OF and CASE TYPE OF even work for initial reference variables. Then they check if an up cast is possible.This can be helpful for checking the static types of formal parameters or field symbols that are typed generically. Therefore IS INSTANCE OF is not only instance of but might also be labeled as a type inspection operator.

For more information see:

To report this post you need to login first.

29 Comments

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

  1. Volker Wegert

    Horst,

    thank you very very much – this is excellent news. I like the new CASE syntax; it might take a little getting used to, but it should come in handy.

    (I won’t spoil the party by asking when 7.50 will be available to “regular” customers – yet :-)).

      Volker

    (0) 
  2. Peter Inotai

    Hi Horst,

    It’s really cool. We had a helper method for this, but this way it’s much easier.

    Any downport planned for this (and generally for 7.50 features)?

    Thanks,

    Peter

    (0) 
    1. Horst Keller Post author

      Any downport planned for this (and generally for 7.50 features)?

      Man, your’e killing me … πŸ˜‰

      But even I dare to say, that you might better not expect that.

      (0) 
      1. Peter Inotai

        Man, your’e killing me … πŸ˜‰

        No, I don’t want to do that. That would be the biggest loss ever for the ABAP community πŸ™‚


        But even I dare to say, that you might better not expect that.

        That’s sad πŸ™

        (0) 
  3. Vasil Bachvarov

    Great news, Horst!

    It’s so cool to see developers who listen to their community.

    From my perspective this would make RTII code so much nicer to read. Thumbs up!

    (0) 
  4. Raphael Pacheco

    Great blog Horst!

    I liked this new way of making the casting. This 7.5 is making me very curious, I do not even have be delighted to use the ABAP 7.4 SP 8 and you already shows this beauty 7.5 πŸ™

    So… we have any news about the CDS too?


    Warm regards,


    Raphael Pacheco.

    (0) 
    1. Horst Keller Post author

      Isn’t that a totally different question?

      I guess there is no simple solution. I expect that the ABAP runtime interprets the symbolic names ZCL_SUPER=> and ZCL_SUB=> in order to point to the method and forgets about it. Why should it keep the information? In fact I have a similar problem: Is there a simple way to find out the name of an actual parameter passed to a formal parameter inside a method? It isn’t! I ended up in interpreting the call stack and parsing the calling code!

      (0) 
      1. Christian Guenter

        In fact I have a similar problem: Is there a simple way to find out the name of an actual parameter passed to a formal parameter inside a method?

        I’m curious, why do you want to know this?

        (0) 
        1. Horst Keller Post author

          DATA itab TYPE TABLE OF string.

          itab = value #( ( `a` ) ( `b` ) ).

          cl_demo_output=>display( itab ).

          I want “itab” as title for the output …

          (0) 
      2. Matthew Billingham

        “… I ended up in interpreting the call stack and parsing the calling code!” But all nicely encapsulated in like this, yes?

        if parameter->get_actual_parameter_name( ) …

        (0) 
      3. Jānis B

        I once tried to find out if there is an easy, generic way a method could determine own “parameter bindings”, in order to implement generic method call “caching” mechanism (caching of method call results)… and didn’t find any πŸ™‚

        (0) 
  5. Tolga POLAT

    Hi,

    Is there any plan for class constuructor with setter method. Like this

    data(oref) =

    new class_type( some_parameter )->set_other_parameter1( other_parameter1 )

                                                            ->set_other_parameter2( other_parameter2 ).

    I know this is not releated but I just wonder.

    (0) 
    1. Horst Keller Post author

      I’m not sure if I understand your question (class constructor?), but the above syntax worked for NEW since it was introduced with ABAP 7.40, see NEW – Classes:

      Like an object reference variable of the type class, a constructor expression NEW class( … ) can be specified before the object component selector -> and in chained attribute accesses and chained method calls.

      (0) 
      1. Tolga POLAT

        Sorry for my bad English πŸ™‚

        Let me explain my question like this:

        in JAVA  we can use setter method like this :

        class mycls{

        private int counter;

        private string text;

        public void mycls(int i){

             this.counter = i;

        }

        public void set_text(string text){

        /* this is optional attribute */

        this.text = text;

        }

        }

        now we can use this code like this:

        mycls my_cls = new mycls(5).set_text(“This is setter”);

        I try to explain this kind of usage of setter method.

        (0) 
        1. Horst Keller Post author

          Let me answer in ABAP:

          CLASS mycls DEFINITION.

             PUBLIC SECTION.

               METHODS:

                 constructor IMPORTING i TYPE i,

                 set_text IMPORTING text       TYPE string

                          RETURNING VALUE(ref) TYPE REF TO mycls.

             PRIVATE SECTION.

               DATA:

                 counter TYPE i,

                 text    TYPE string.

          ENDCLASS.

          CLASS mycls IMPLEMENTATION.

             METHOD constructor.

               counter = i.

             ENDMETHOD.

             METHOD set_text.

               me->text = text.

               ref = me.

             ENDMETHOD.

          ENDCLASS.


          Now we can use this code like this:


          DATA(my_cls) = NEW mycls( 5 )->set_text( `This is setter` ).


          The difference to your Java code is, that set_text must return the self reference me explicitly. Otherwise, you cannot chain in ABAP but have to write two statements.


          CLASS mycls DEFINITION.

             PUBLIC SECTION.

               METHODS:

                 constructor IMPORTING i TYPE i,

                 set_text IMPORTING text       TYPE string.

             PRIVATE SECTION.

               DATA:

                 counter TYPE i,

                 text    TYPE string.

          ENDCLASS.

          CLASS mycls IMPLEMENTATION.

             METHOD constructor.

               counter = i.

             ENDMETHOD.

             METHOD set_text.

               me->text = text.

             ENDMETHOD.

          ENDCLASS.

          ...

          DATA(my_cls) = NEW mycls( 5 ).

          my_cls->set_text( `This is setter` ).


          (0) 
          1. Tolga POLAT

            Thanks for your reply. I didn’t know if we return class itself, we can chain. But I prefer your second example in my code.

            Actually I’m not Java developer, But I couldn’t explain myself without writing code πŸ™‚

            (0) 

Leave a Reply