Keyed collections and getting the key

I fear this will be my “Carthago delenda est“: Furthermore, I believe the Lansa documentation is severely lacking.

Case in point, today, using Visual Lansa 14.1 and the online and up-to-date documentation, I wanted to use a keyed collection. I wanted to use this in a way where I can later loop through the collection getting keys and values.

Now, had I started on 7.60.1 FOR Parameters I might have guessed this earlier, but I didn’t. I started on Keyed Collection (PRIM_KCOL). Silly me.

It does tell me how to define a keys collection but in a roundabout way. So the definition goes like this

#PRIM_COL

Like:

Define_Com Class(#PRIM_KCOL<#PRIM_VAR #CHAR512>) Name(#COL1)

which defines a collection #COL1 with keys of type #CHAR512 and values of the variant type, #PRIM_VAR. You have to use repository fields as the key type for some reason, but there is no such requirement for the key value.

Now, #COL1.ItemCount can tell me how many pairs of keys and values are in the collection but there is no way to use this to iterate through the collection.

Since I had not started on the FOR page I tried this:

For Each(#COL1_VAL) In(#COL1)
#COL1_KEY := #COL1.KeyOf<#COL1_VAL>
...
Endfor

which actually works. I did however suspect that it could have some form of performance issues and also would only work consistently if all values were unique.

But wild and semi-random searching of the documentation lead me to the poorly demonstrated Key parameter for the For loop:

For Each(#COL1_VAL) in(#COL1) Key(#COL1_KEY)

This works.

I have also tried to find the documentation on the different assignment operators. I know what +=, -=, *= and /= does, but apparently I don’t know what := does since sometimes I need to use <=:

#VAR_OBJ <= #COL1<#COL1_KEY>
...
#COL1_VAL := #COL1<#COL1_KEY>.String
...
#COL1_VAL := #VAR_OBJ.String

I am guessing <= passes a reference while := assigns a value.

Furthermore, I believe the Lansa documentation is severely lacking.

ModalResult

I will swear that the documentation does not contain any information about what happens when you assign a value to the ModalResult property of a form. In fact, ModalResult is a property of push buttons (PRIM_PHBN), but when a button is pushed, the ModalResult is supposed to be migrated to the form as well.

This became apparent when I had a form with a reusable that tried to catch invalid input when the user clicked on a button. Unfortunately, the reusable sent a signal to an event which then set the ModalResult property, closing the form no matter what I tried to do.

It turns out that assigning a value to ModalResult closes the modal form immediately.

Evtroutine Handling(ÆPHBN_1.Click)
  If Cond(...)
    ...
  Else
    #COM_OWNER.ModalResult := OK
  Endif
Endroutine

 

AsInteger and AsNumber

There’s a special place somewhere for whoever thought of this. The intrinsic functions AsInteger and AsNumber work in very different ways and I believe they are so badly named that this “feature” is a bug.

Anyway, that is how it is in RDMLX.

So.

Which of these functions can be used to convert the content of a string to a numeric value? Like the string “53”?

Yes, it is a naughty example, because if you run both of these on Windows you get the same result, 53.

#STR := "53"
#NUM := #STR.AsNumber /* returns 53 */
#INT := #STR.AsInteger /* returns 53 */

But that is a trick. On IBM i I would have needed to use “242” to get the same value from both functions because

AsInteger returns the character code of the first character in the string

True, that will be an integer, but the name of the function is terrible.

The reason the code above gives the same result is that the character code for “5” in ASCII (Windows) is 53, while the character code for “2” in EBCDIC (IBM i) is 242.

It does not matter how long the string is, AsInteger will only look at the first character.

But really, it should have been called something with CharCode.

Having said that:

As long as I don’t care about character codes, it is AsNumber I need to use.

V.14.1 still crashes on invalid XSLT

The bug I wrote about some time ago with invalid XSLT still exists in v.14.1

That time it was missing the <tbody> in a <table>. This time it was an <input> inside a <tr>. Obviously wrong, I know, but apparently whichever version it was written in back in 2010/2011 allowed it and today, when I wanted to do an edit, the editor crashed.

The <input> was moved to the <td> within the <tr>.