iin() + global functions overloading


Link to this posting

The function iin(<value>, <array>) reports if the value, passed as the 1st argument, appears in the array, passed as the 2nd argument.

Writing Oracle PL/SQL code, I always enjoy the ability to use the SQL's IN clause in a procedural environment:

Code: Select all
if v_day in ('SATURDAY', 'SUNDAY') then
   -- do something
end if;

Of course, we can mimic it in PowerScript using the choose case construction (the price - one extra line of code):

Code: Select all
choose case ls_day
case 'SATURDAY', 'SUNDAY'
   // do something
end choose

Unfortunately, it's impossible to utilize the choose case construction to assign the comparison's result to a Boolean variable. :( To do that, we need to use a Boolean expression with OR:

Code: Select all
lb_weekend = (ls_day = 'SATURDAY' or ls_day = 'SUNDAY')

That solution is not very elegant - a same variable is mentioned in code more than once. And if you need to compare to 30 values, not with just 2? Besides, we, database people, love normalization :lol: .

So, let me introduce the iin() function ("internal in"). It reports if the value, passed as the 1st argument, appears in the array, passed as the 2nd argument:

Code: Select all
lb_weekend = iin(ls_day, {'SATURDAY', 'SUNDAY'})

Of course, you can use a preliminarily populated array:

Code: Select all
string ls_days[] = {'SATURDAY', 'SUNDAY'}

lb_weekend = iin(ls_day, ls_days[])

It's totally impossible to use an array with choose case - you are forced to write a whole loop fragment instead of a single line of code with iin()!

One more example - this time with numeric data:

Code: Select all
if iin(ll_employee_id, {123, 456, 789}) then

You can ask: how did I overload a global function in PowerScript? It's impossible! Not for me - I have a personal permission from the president of Powersoft Sybase SAP Appeon :lol: ! Ok, it's true that we cannot overload global functions in the Function Painter, but the source code can pass through a surgical operation. So, firstly create a normal, not-overloaded global function, save it and then re-open in with "Edit Source" and add the needed overloaded versions manually. After you add iin() to your application, explore its source code using the "Edit Source" mode.

HOW TO ADD THE FUNCTION TO THE APPLICATION

1. Save the file spy.pbl on your hard disk (in the folder where the PBLs are stored). The function is in that PBL.
2. Add it to your application's library list.

I have described how to overload global functions only for the sake of overloading existing global functions if a need arises. Don't create new global functions (the reasons are described here). If the old global function, being overloaded by you, would be created as an object's method (i.e. in the right way), you would not be forced to use the described trick to overload it.

Link to this posting

Hello Michael,

I wonder why you use the REF keyword in the prototype of the function :

Code: Select all
global function boolean iin (ref powerobject apo_val, ref powerobject apo_arr[]);


An object is anyway passed by reference...

Link to this posting

There are situations when we pass objects by value and it doesn't work. Don't ask me why - PB is so strange... I believe you if you say it would work by value in that case. And I understand what you mean (you ask why I use "pointer to pointer" instead of a "pointer"), but we simply always pass objects by ref and it always works.

Link to this posting

It's strange because I've never used REF when I pass an object and I had no issue with that...

Link to this posting

REF keword acts as a comment for developers. It is not forced by the compiler, but that optional keyword can help understand scripts, especially when the called function has a mix of "in" and "out" arguments.