Using Progress 4GL v11.1 (*)
So, here I am with my nice new shiny object-parameter based way of passing, well, parameters.
Fly in the ointment is that over the years, the current menu system has needed to pass various parameters to bits of code, and as I got better at coding (!) I changed these parameters. However, being the lazy sod that I am, I didn't want to have to revisit all the old code and change all the input parameters.
Hence the new object-parameter mechanism. One parameter to rule them all.
Right, thought that I would be smart and rather than trying to maintain a list of what is old and what is new, try to run the program the "old" way, and catch any error and rerun using the new way.
Until I came across this scenario:
/** foo.p [old-style parameter passing]
def input parameter p_code as char no-undo.
message substitute("running foo with code &1",p_code) view-as alert-box information.
/** end foo.p */
now try running this code:
routine-level on error undo, throw.
do on error undo, throw:
run custom/custom2.p (new Progress.Lang.AppError("foobar",1)).
catch e as Progress.Lang.Error :
message e:getmessage(1) skip e:GetMessageNum(1) view-as alert-box.
Change "as char" to "as int" or "as logical". "as datetime" doesn't work (but is not the right error). "as date" gives some interesting results
I suspect that the actual data being passed as a parameter is some form of integer pointer and therefore progress does some of this "automatic type conversion" rubbish that can throw you.
Doesn't help me, though ...
* yes, I did mean 4GL. None of this new-fangled ABL stuff for me. No sirrreee.
This is really 4GL behaviour (aka old). I suspect the ABL is trying to coerce or box the type from the value into the parameter type. The closest match the ABL finds is the integer representation of the object (the reference) and uses that.
If you call foo.p as follows, you'll see '20', typically. I would equate your reported behaviour with the below.
run custom/custom2.p (session:handle).
From TFM on "Parameter passing syntax":
For procedures, the data
type of parm must be compatible
with the data type defined for the parameter. Procedures allow the
matching of a wide variety of different data types between the passed parameter and the parameter definition. When it
can, the AVM converts the passed value from the source data type to an
appropriate value in the destination data type, depending on the direction
mode) of the passed value.
For procedures, the AVM checks data type matching and appropriate overflow
conditions at run time.