Let the compiler help you

An interesting question posed by a relatively new user came up on the forums. It had to do with how the Array() function worked and how he could force it to return an array of variants to call his method.

His method was defined like

BuildMenu( base as menuitem, params() as variant)

And he would call it like

Result = BuildMenu (base, Array ("Run", False, "Edit", "Rename", "Delete") )

and this would build up a menu from the base item and append menu items to it. Those new menu items were configured by the array of variants

‘False’ means the previous menu item is disabled (‘True’ means it is enabled, but is optional and assumed)

Because the boolean elements are optional, it is possible to make a call using only string elements, such as:

Result = BuildMenu (base, Array (“Run”, “Edit”, “Rename”, “Delete”) )

But when I do this, I get the following compile error:

So he’s trying to figure out how to force Array to return variants ALL the time. Which is the wrong question to ask in many ways.

Using an array of variants means the compiler cannot help you out and tell you when you are trying to assign the wrong kind of value to another.

Normally if you did something like

dim foo as integer
foo = "123"

the compiler will warn you about this. But if you change this simple code to :

dim foo as variant
foo = "123

you will no longer get a compile error. And depending on how you use “foo” you may, or may not, get some kind of runtime error.

This is why some of the long time users of Xojo suggest avoiding variants unless you absolutely cannot do something any other way.

Variants make it possible to bypass and avoid type checking by the compiler. What this means is that by using a variant you are possibly only finding out about errors at runtime because the compiler cannot do its normal helpful type checking to make sure you catch errors early on.

So in this particular thread on the forums the right question isn’t “how to force the array() function to always return a variant array” but “how to design this particular API so variants are not required”. And that is certainly possible since Xojo supports variable argument lists, optional parameters and other features that retain strong type checking at compile time AND still allow for a good degree of flexibility in designing an API.

And I made a suggestion on that thread :

Result = BuildMenu (base, BuildItem( “Run”, false), BuildItem(“edit”), BuildItem(“Rename”), BuildItem(“Delete”))
with buildmenu defined as

Sub BuildMenu(base as menuitem, paramarray items as menuitem)
// just append the items passed to the base
for i as integer = 0 to items.ubound
base.append items(i)
end sub

and BuildItem as

Function BuildItem(name as string, enabled as boolean = false)
dim item as new menuitem(name)
item.enabled = enabled
return item
end function

Avoid variants where you can and design an API that permits the compiler to help you out at compile time. The earlier you catch possible bugs the easier, and less costly, they are to fix.

The compiler can help you IF you let it.