First off this is very, very, technical, so unless you are in love with the minute details of ABAP programming you might not be that interested. Luckily, lots of people have just such a love affair.
In a previous blog
I talked about how Australian SAP expert Chris Paine had asked if I could pass in an array of values as opposed to having ten input parameters.
This is very common in programming world the best example is the MESSAGE statement in ABAP where SAP have decided that four parameters are all you will ever need, and you have MSGV1 to MSGV4. As an aside I find it a daily source of hilarity that in SAP you have about six message structures, all different so you have MSGTP, MSGTYP, TYPE etc, all for the same thing. It is fairly clear that the word “REUSE” had never been heard of at SAP interanlly, at least in the past.
So, in the blog above I describe creating a ZCL_BC_PARAMETER class where using recursion I can pass in one to a million parameters, howevere many I feel like, all of different types.
That worked, all was good, but I was not happy Jan (that reference would make no sense outside Australia).
I was not happy because I had tied my PARAMETER class to my LOGGING class and they were “tightly coupled” (oh-err missus) so a change to one might mean a change to the other and you could not use the PARAMETER class on it’s own in another context. All the OO books that I read say this is a Bad Thing.
I could not rest easy in my bed until I had a solution to this. So, yesterday, as I came home on a Saturday night, as drunk as drunk can be, I saw a solution inside the computer, where my own solution should be. So I called my wife and I said to her, will you kindly tell to me, who owns that solution inside the computer where my own solution should be?
“Oh, your drunk, your drunk, you silly old fool, still you cannot see – that’s an ITERATOR that my mother sent to me”
Well it’s many a day I travelled, a hundred miles or more, but a proper iterator in SAP, I never saw before.
Now, an iterator just does something rather akin to looping through an internal table full of different types of things. The problem is an internal table is supposed to consist of lines that are exactly the same e.g. a structure such as VBAP. You don;t have the first line looking like VBAP and the second line looking like LIPS.
I have passed in a lot of random things, different each time. Luckily this is not a problem in ABAP due to the so-called dynamic duo, oh sorry that’s Batman and Robin, I mean the so called dynamic data objects.
Before I started I thought to myself – I am sure I have seen the iterator pattern used in standard SAP, it’s used in ABAP2XLS as well. Why don;t I go looking for an iterator interface. I do a search and sure enough there are twenty billion, all slightly different. Clearly every time there is an internal project in SAP to add a new function that needs an iterator (or whatever) the developer is horrified at thought of looking at what went before, and makes up there own new one, and then calls it a name specific to their project e.g. CL_SCOTTISH_TREE_EATING_ITERATOR to make sure no-one can ever re-use it in a future project. Then they go off and give us “customers” a stern talk about how re-use is the be-all and end-all of life.
So, sod it, I’ll write my own. My current use case is sending different sorts of values into the application log, but another use case I can think of is having an exception class where I can pass in three values, or five values, or however many I want. That way I don’t have to write a different exception class each time with a set number of input paraemeters with concrete types.
As we have seen, I have the calling program send in a random number of parameters – the below is far more verbose than you would probably want, I am just hammering home a point.
CALL METHOD do_something( io_input_parameter = zcl_bc_parameter=>get( value = ld_i_am_a_string
predr = zcl_bc_parameter=>get( value = ld_i_am_a_quantity
prder = zcl_bc_parameter=>get( value = ld_i_am-a_money_value ) ) ) ).
Then, inside the DO_SOMETHING I need a way to “unpack” the values that I have just been given. I am going to put all the instances of the parameter class passed in into a static internal table.
FIELD-SYMBOLS: <value> TYPE any.
IF if_i_am_first = abap_true.
CLEAR mt_parameters.”Static table
APPEND me TO mt_parameters.
CHECK mo_predecessor IS BOUND.
This is using the recursive call I described before to loop trhough all the parameters passed in and out them in an internal table.
Now, it is quite clear that ABAP wishes it was Java, despite Java being owned by Oracle, and every release of ABAP brings the two languages closer together Given that, I might as well use the Java type synatx when dealing with iterator behaviour as oppsoed to evil behaviour like looping over an internal table. Who would do such a horrible thing? That is so ten minutes ago.
IF mt_parameters IS NOT INITIAL.
rf_yes_it_does = abap_true.
rf_yes_it_does = abap_false.
DATA:lo_parameter TYPE REF TO zcl_bc_parameter.
READ TABLE mt_parameters INTO lo_parameter INDEX 1.
IF sy-subrc <> 0.
ro_value = lo_parameter->mo_do_value.
DELETE mt_parameters INDEX 1.
There we go, the parameters class is now totally independant of the logging class. I told Donna Summer – she was very impressed and told me “this state of independence will be, this state of independence will be”.
OK, in my logging class I have passed in an IO_INPUT_PARAMETER an instance of my parameter class.
io_input_parameter->unpack( abap_true ).”i.e. clear static table
WHILE io_input_parameter->has_next( ) = abap_true.”oh, matron, just like Java
lo_do_value = io_input_parameter->next( ).
ASSIGN lo_do_value->* TO <value>
CHECK <value> IS ASSIGNED.
add_input_to_log( EXPORTING id_input = <value>
CHANGING cd_message = ld_message ).
There we go. The dependencies have been removed, I am sure the “gang of four” who wrote the book on design patterns would be really pleased with me if they were not too busy bursting into flame and turning invisible and extending their arms to twenty foot long.
Just to lighten the load of heavy techincal ABAP I would just like to leave you with two totally unrelated things. Firstly, here is an SAP job advert that was emailed to me from Germany the other day. This company, based in Munich, is looking for SAP experts. I have to say you don’t get SAP job adevrts like this in the UK or Australia.
On an even more unrelated note, before I became an Australian citizen, I lived in the West Country of England, near Bristol. I would just like to introduce the world to a pop group from that next of the woods who have been going strong since the 1960’s.
This is the Wurzels version of Pulps’ “common people”. The lyrics are almost exactly the same as far as I can tell, but I think there are more farm animal noises than in the original. The accent of the lead singer reflects the way I spoke when I was young, I had to learnt to tone this accent down or no-one would be able to understand a word I said.
Anyway, that is it for now, time to go down the pub.
If anyone woud like to tell me what is wrong with my PARAMETER class as described above, or tell me how to achieve the same thing in a better way, I am all ears.