ABAP Language at TechEd 2013 – Rock Your Code with ABAP 7.40!
In workshop CD261 at this years TechEds you will get your hands on expression enabled ABAP 7.40.
As almost every year the question arised, what kind of exercise can we offer to you, Two years ago, I prepared a pocket calculator simulation that was written in old style code and that the participants had to refactor to expression oriented code as far as possible with ABAP 7.02. Since gamification is such a buzz word and since another subject of the workshop – ABAP Channels – is also exemplified by a game, we (Holger and myself) have decided to also use a gaming example for expression enabled ABAP this year. We searched for an existing game programmed in ABAP and prepared it in such a way that it is usable for an exercise.
The existing game
As a suitable game we found a Jawbreaker adaption in Enno Wulff’s Trick Tresor: Well, if you look at the code, you see typical ABAP as you can find tons of it in real life programs: full of forms, OCCURS, WRITEs, … (and comments and names in German) but no offense!. We like the idea of the game but it cannot be an exercise template in such a pre ABAP Objects state .
Refactoring the game for ABAP 7.0
Theerfore, we have rewritten the game in such a way that it represents a state-of-the-art 7.0 ABAP program. The new version uses ABAP Objects instead of subroutines of course and no other obsole statements any more. And since classical list programming is regarded as a kind of old fashioned, the game interface is realized as an HTML file shown in a browser control (but we will also offer a list based version):
You find the source code of the refactored game attached as Z_BLOCKS_HTML_700.txt. You can copy the code to your 7.02 or 7.0 sytem and run it happily there (since the convenience class CL_ABAP_BROWSER is not yet available in 7.0, you have to replace it with CL_GUI_HTML_VIEWER and use an own custom control there). But the game is not the aim.
Express the game in 7.40
The aim is to beautify the ABAP code by replacing statements and helper variables with expressions whilst the functionality stays the same. This will be an exercise of the 2013 TechEd workshop. I could attach the full solution right now, but I won’t (no cheating!). All I will say is that you can reduce the amount of lines by 35% by introducing expressions as shown in the following code snippets:
Example 1
Z_BLOCKS_HTML_700
DATA:
rnd_color TYPE REF TO cl_abap_random_int,
seed TYPE i.
seed = sy-uzeit.
rnd_color = cl_abap_random_int=>create( seed = seed min = 1 max = 4 ).
Z_BLOCKS_HTML_740
DATA(rnd_color) =
cl_abap_random_int=>create( seed = CONV i( sy-uzeit ) min = 1 max = 4 ).
Example 2
Z_BLOCKS_HTML_700
READ TABLE field INDEX x ASSIGNING <column>.
READ TABLE <column> INDEX y ASSIGNING <color>.
Z_BLOCKS_HTML_740
DATA(color) = field[ x ][ y ].
Example 3
Z_BLOCKS_HTML_700
CASE <color>.
WHEN 1.
color = `lightblue`.
WHEN 2.
color = `cornflowerblue`.
WHEN 3.
color = `darkblue`.
WHEN 4.
color = `steelblue`.
ENDCASE.
DATA:
xn TYPE n2,
yn TYPE n2.
xn = x.
yn = y.
CONCATENATE
html
`<td bgcolor=”` color `”>`
`<a href=”sapevent:x` xn `y` yn
`” style=”text-decoration:none”>` square `</a></td>`
INTO html.
Z_BLOCKS_HTML_740
html =
html &&
|<td bgcolor=”{ SWITCH string( color WHEN 1 THEN `lightblue`
WHEN 2 THEN `cornflowerblue`
WHEN 3 THEN `darkblue`
WHEN 4 THEN `steelblue`) }”>| &&
|<a href=”sapevent:x{ CONV n2( x )
}y{ CONV n2( y )
}” style=”text-decoration:none”>{ square }</a></td>|.
And of course, you can get your hands on ADT (Eclipse) for rewriting the code …
See you at TechEd!
Looking forward to rock with you and your code in Amsterdam 🙂
Nice to see how ABAP is getting better and more up to date!
Good one!!!
WOW impressive changes to the code!
I'm realy looking forward to the upgrades of our systems.
Wow, it's certainly compact. But I wonder what the 'vision' is behind this revamp of ABAP.
Does it make ABAP more robust? More efficient? More human-friendly?
From a support viewpoint, do these stylistic changes make the code easier to understand and enhance?
I don't want to be a wet sock, but IMHO those issues are far more important than reducing the number of code lines by 35%..
I remember that C programmers used to hold competitions on how much functionality could be packed into one single line of code. The results were amazing - and totally impenetrable 😕
cheers
Paul
In fact, it is about making ABAP more robust, more efficient, more human-friendly.
I'm not talking about old and clunky reports with forms and lists and dynpros and so on. In such legacy code it might not make too much sense to mix in modern features. But for new programs, we are living in times of using more and more object oriented APIs, even in ABAP. And if you write object oriented programs or use object oriented APIs it is simply better to write also ABAP in a modern way. It is not stylish but simply state of the art. Why should I write
CALL METHOD meth EXPORTING para = value
RECEIVING res = result.
If I can write
result = meth( value).
And new features like inline declarations or expression positions simply take us one step further. Instead of
READ TABLE itab INTO wa INDEX idx.
DATA result TYPE something.
result = meth( wa ).
You can now write
DATA(result) = meth( itab[ idx ] ).
If used responsibly the new features can in fact make code more clear.
Say, the task is to read a value from a nested internal table. What is more clear?
This
DATA wa1 LIKE LINE OF itab.
DATA wa2 LIKE LINE OF wa1-col2.
DATA wa3 LIKE LINE OF wa2.
DATA num LIKE wa3-col1.
READ TABLE itab INTO wa1 INDEX 2.
READ TABLE wa1-col2 INTO wa2 INDEX 1.
READ TABLE wa2 INTO wa3 INDEX 2.
num = wa3-col1.
or this?
DATA(num) = itab[ 2 ]-col2[ 1 ][ 2 ]-col1.
Of course, there is also the danger of obfuscation. So, code responsibly. The aim of the new expression enabling is making code more clear (see example above) and not less clear. Therefore and for the sake of maintainability, expressions should not be used for expression's sake. One or the other helper variable used inbetween can help debugging a lot. Another trap can be performance. Writing too much expressions can result in too much operations.
Nevertheless, if used with a sense of proportion the new stuff can make your programs
better to handle.
As a last example: You have to use an API with a factory and a method that expects a given type only once in your program. What is better?
This
CONSTANTS id TYPE i VALUE 17.
...
DATA:
factory TYPE REF TO cl_factory,
id_string TYPE string.
CREATE OBJECT factory.
id_string = id.
factory->service( id_string ).
or this?
CONSTANTS id TYPE i VALUE 17.
...
NEW cl_factory( )->service( CONV string( id ) ).
Best
Horst