ABAP News for Release 7.50 – IS INSTANCE OF
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:
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
big pictures, big pictures ... š
big pictures = huge distances š
Same for me ...
Deep inside can be as far as far outside š
I have been relegated to ABAP 700. Can't even use AiE š
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
Man, your'e killing me ... š
But even I dare to say, that you might better not expect that.
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 š
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!
Another nice use case could be catching a general exception and finding the concrete exception with INSTANCE OF or CASE TYPE OF.
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.
Yes ...
I'm sure there will be some blogs about them with more details. But if you can't wait, there are already some info here:
ABAP Tools - What's New in SAP NetWeaver 7.5 (Release Notes) - SAP Library
Thanks Peter š
Warm regards,
Raphael Pacheco.
Here we go ...
Wow! So fast šÆ
Thanks Horst !
P.S.: Sorry for posting just now thanking the link.
Thanks for posting!
Ah, but is there a solution to Mike Pokraka's question Determine class name used for calling a static method?
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!
I'm curious, why do you want to know this?
I want "itab" as title for the output ...
"... 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( ) ...
yes
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 š
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.
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:
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.
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` ).
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 š
Cool feature! Ihave used it until now sometimes in my own coding. But it cannot help me by the following problem: assume having an internal table of references, i.e. as a result from the query manager (as part of the persistence framework)
In order to process the result, iĀ have to loop and cast to the right persistence:
because instances is of type OSREFTAB and persistence my own class.
It might be of interest to be able directly loop and cast in one step.
Ā
I see, you want something like
Can't you simply use the CAST operator in the loop instead?
Ouch, it was not clear in your post that CASTING was syntaxically incorrect, and IĀ searched the most recent documentation because I didn't know this syntax. Maybe a little comment to say it explicitly ? like "<== invalid, CASTING not allowed here
... that was my first try also, but doing so I will get a syntax error:
Sure, because we don't support it and I guess we won't, because you can use the CAST operator.
What a pity!Ā To illustrate it, i have written thes lines of code:
Maybe, that the CAST-Statement is sufficient, but casting directly in the loop statement maybe a little bit smarter. The line doing the casting is quite obvious and can be supported by the abap language like the way of all the 'new' statementsĀ introduced in 7.40/7.50, which makes the coding much more smarter and readable. Nevertheless, thank you for giving this information.