Skip to Content
Technical Articles
Author's profile photo Mahesh Palavalli

Don’t “LET” it fool y’all Javascript folks. ABAP “LET” vs JavaScript LET.

So recently in a program, I am trying to clear couple of columns in an internal table. So instead of doing it the regular old way of looping into reference and clearing those fields, I used the new ABAP to do that job. Don’t reason with me on this, I am addicted to the new ABAP ๐Ÿ˜› .

The first issue I faced is the internal table getting cleared completely(emptied) instead of just clearing just one column. See the code below:

test_table1 = VALUE #( FOR <test_line1> IN test_table1 ( VALUE #( BASE <test_line1> field1 = '' ) ) ).

This exact issue is pointed out in the below blog. So the ‘VALUE’ operator clears the left side before the processing of the right side and so it will return empty table instead of clearing it. See that blog in case if you’ve missed it. It is very interesting.

https://blogs.sap.com/2019/05/27/abap-traps-dont-self-reference-in-constructor-operators/

Now for this, I did the same. I used the “LET” expression to store my internal table data in a temporary table and cleared the column. Now test_table1 data will be cleared after assigning the test_table1 data to temp_table and we will do the for loop on temp_table.

test_table1 = VALUE #(  LET temp_table = test_table1 IN FOR <test_line1> IN temp_table ( VALUE #( BASE <test_line1> field1 = '' ) ) ).

 

It worked ๐Ÿ™‚ and it was all fun and games until my boy ABAP compiler started to throw errors ๐Ÿ˜€ .

The thing is I assumed that the LET expression in ABAP behaves same as the LET statement in Javascript.

JavasSript “let”:

The difference is in the Javascript, LET variables are block scoped, if the control comes out of the block(if or for loop etc..,), the LET variable will lose it’s scope and becomes undefined.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

ABAP “LET”

But in ABAP, LET variables behaves similar to a normal variable declared using DATA except that you cannot access it outside the constructor expressions but they can be reused inside other constructor expression but we should pass the same type to the LET variable and it will become initial.

This is the reason for my errors as I’ve used the same LET variable to clear multiple tables.

There is an another way given by SAP where we can use the field symbol in the LET expressionย  and you might think that it will hold the reference of the assigned variable and will be again be assigned with a different type in an another constructor expression( VALUE #( ) etc., ) but guess what, even the field symbol type is also fixed once used in the LET expression.

Note: It will not work the same way as variable ( LET <fs> = table will not work), I tried it with a different approach and found that it still fixes the type of <fs> and will not be updated in an another LET expression.

Obviously I shouldn’t compare two different languages as they have their limitations. But it would be nice if it works the same like a JavaScript “Let” variable at least the field symbol part of it. (in the future)

 

ABAP Documentation Link:

https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abaplet.htm

 

UPDATE:

If you simply want to clear a column without conditions you can go for modify or corresponding using except. For conditional based you can go with this approach. see the comments below by Alexander and Dmitriy Kurshakov

https://blogs.sap.com/2019/07/15/dont-let-it-fool-yall-javascript-folks.-abap-let-vs-javascript-let./#comment-466188

 

BTW keep the let expression name simple. See the comments below bySuhas Saha

https://blogs.sap.com/2019/07/15/dont-let-it-fool-yall-javascript-folks.-abap-let-vs-javascript-let./#comment-466230

 

 

Regards,

Mahesh

 

 

 

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Yes, scope in ABAP and JAVA are different. But if you want to use

      FOR wa IN blah...
      FOR wa IN blah2...

      with the same wa, then that could be considered an indication that, in accordance with clean code ideals, you need to modularise further.

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Okay, firstly I am talking about JavaScript not JAVA. Both JAVA and ABAP are strongly typed where as JavaScript is untyped and that is reason why ABAP might not be allowing the same LET expression variable to store different types. I agree both are different and so Iโ€™ve metioned in the blog that I shouldโ€™nt compare and it would be nice to have atleast in the field symbol as a field symbol can be untyped and can take any ref at runtime.

      But from the ref code you posted wa cannot be used in two different constructor expressions if blah and blah2 are of different types. or did I missed your point?

      Thanks,
      Mahesh

      Author's profile photo Matthew Billingham
      Matthew Billingham

      I think possibly you have missed my point. If you want to reuse a variable within such an expression then that indicates two possible "code smells".

      1. You need to modularise further - i.e. you shouldn't have two expressions like that in a single modular unit and it would be better for them to be in their own methods
      2. You should really be giving them separate more meaningful names.

      Having said that, I did recently come across a case where 1 and 2 didn't apply, which was a bit of a pain.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      ?ย  I missed that. Agree, in some cases you really donโ€™t need those 2 points.

      For eg. the blog case only. You see I named my table as temp_table just for a reason that it is just a temporary storage of table data and I really donโ€™t have a much use for that. imagine it with field symbol

      LET <fs_temp_table> = table1.

      LET <fs_temp_table> = table2.

      It would be so nice to have that but it is not possible as LET behave like a type declaration of the assigning variable/table type.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Just so long as you don't actually prefix all your field symbols with FS... I mean the angle brackets already tell you it's a field-symbol! ๐Ÿ˜‰

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      ๐Ÿ˜€ ๐Ÿ˜€ you caught me there ๐Ÿ˜€ .. Old habits die hard ๐Ÿ˜€ .. But again I am trying my best not to do those redundant things these days ๐Ÿ™‚ ๐Ÿ™‚

      Author's profile photo Alexander K
      Alexander K

      Hello Mahesh.

      Maybe simple way to clear field in internal table is:

      modify test_table1 from value #( field1 = ' ' ) transporting field1 where field1 not is initial.

      It is new Abap syntax too.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Nice. Sometimes old ways are the best and easiest ways ๐Ÿ™‚

      I think only the 'Value' part is the part of new ABAP and modify is still old. I just gave a simple example and I was actually doing a condition based clearing.

      But anyways the point is to tell that LET in ABAp and JavaScript are not so similar and it wouldn't even work the same way if we use field symbol in the LET expression which is a bummer.

      Thanks,

      Mahesh

      Author's profile photo Dmitriy Kurshakov
      Dmitriy Kurshakov

      Hi. I think, you also may try

      test_table1 = CORRESPONDING #( test_table1 EXCEPT field1 ).
      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      Nice and very useful tip. But like I said, there is conditional based clearing and as per my knowledge I doubt if it is possible with corresponding. Or it it? let me know if it is possible.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      but I prefer the โ€œnewest 6.10โ€ FIELD1 IS NOT rather than the โ€œelderโ€ NOT FIELD1 IS and rather than the โ€œweirdโ€ FIELD1 NOT IS ?

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      ๐Ÿ˜€ now that I re read it again, it does feel weird ๐Ÿ˜€

      Author's profile photo Suhas Saha
      Suhas Saha
      LET <fs_temp_table> = table1

      I prefer to use short names for auxiliary variables (declared with LET).

      I quote the SAP help documentation,

      The helper variables declared in a LET expression are a good example of where long readable names are not necessary and can even harm readability. The helper variables can only be used in their own expression, which means that short names (possibly even single-character names) are enough.

       

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      ๐Ÿ˜€ Yeah it makes sense and the code looks beautiful as well. I usually go with wa1, wa2 sequence.

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli
      Blog Post Author

      and btw from my observations, we cannot pass a table directly to the let field symbol.