Useful array and variant functions in MBS Plugins

We got quite a few utility functions in MBS Xojo Plugins for you to enjoy in your projects.

GetVariantTypeMBS

Let’s say you have a variant containing something. Usually you use VarType() or Variant.Type to query the type.

GetVariantTypeMBS(va as variant) as Integer

The GetVariantTypeMBS function does the same, but has an extra code path for UInt32 and UInt64. While Xojo’s functions don’t distinguish between signed and unsigned integers, the MBS Plugin can do.

Variant contains Variant.Type GetVariantTypeMBS
Int32 2 2
UInt32 2 102
Int64 3 3
UInt64 3 103

All other types would be same return values.

Here is a sample code, which tries both functions:

Var u As UInt64 = 123
Var v As Variant = u
Var t1 As Integer = GetVariantTypeMBS(v)
Var t2 As Integer = v.Type

// 103 for UInt64, 102 for UInt32 or otherwise same as v.type

Feel free to try this and see the values in t1 and t2.

GetVariantArrayMBS

You may have a variant containing some kind of Xojo array, e.g. an array of dictionary. The GetVariantArrayMBS function checks if a variant contains an object array and returns it to you as a variant array.

GetVariantArrayMBS(VariantContainingArray as variant) as variant()

Normally in Xojo you would have to code different branches for each type of array, so you can try the cast and get an exception when it fails. You may try things like Dictionary, Pair, Window or other classes you expect. But this function returns you whatever object array is in the variant as a variant array. This way you can inspect each element.

Here is a sample code snippet:

Var d() As Dictionary
d.Add New Dictionary
d.Add New Dictionary(1:2)

// convert to variant array
Var v() As Variant = GetVariantArrayMBS(d)

This function raises an exception if variant is nil or the variant is not an object array.

GetVariantArrayUboundMBS

You may want to generically know the upper bound of the array in a variant. The GetVariantArrayUboundMBS function can provide this:

GetVariantArrayUboundMBS(v as variant) as Integer

The function returns -1 for an empty array and -2 for a variant, that does not contain an array.

Here is a sample code snippet:

Var d() As Dictionary
d.Add New Dictionary
d.Add New Dictionary(1:2)

// convert to variant array
Var v() As Variant = GetVariantArrayMBS(d)

// we can query upper bound generically for any array
Var u1 As Integer = GetVariantArrayUboundMBS(d)

// if not an array, returns -2
Var v2 As Variant = New Dictionary
Var u2 As Integer = GetVariantArrayUboundMBS(v2)

GetVariantArrayValueMBS

Now if you have a variant containing an array of objects, you can directly ask the plugin to return you an object for an index using the GetVariantArrayValueMBS function.

GetVariantArrayValueMBS(v as variant, index as integer) as variant

This function raises an exception if variant is nil, index is out of range or the variant doesn’t contain an array. It works with arrays containing object, Int32, Int64, Single, Double, String or Boolean.

Here is a sample code snippet:

Var d() As Dictionary
d.Add New Dictionary
d.Add New Dictionary(1:2)

// queries value of object array generically
Var d1 As Dictionary = GetVariantArrayValueMBS(d, 0)

SetVariantArrayValueMBS

After getting a value, you may wonder how to set a value and we have the SetVariantArrayValueMBS function for this:

SetVariantArrayValueMBS(v as variant, index as integer, value as variant)

If index is upper bound plus one, a new value is appended.

Here is a sample code snippet:

Var d() As Dictionary
d.Add New Dictionary
d.Add New Dictionary(1:2)

// generically adds entry to an array by setting new index
SetVariantArrayValueMBS(d, 2, New Dictionary)

This function raises an exception if variant is nil, index is out of range or the variant doesn’t contain an array. It works with arrays containing object, Int32, Int64, Single, Double, String or Boolean.

ObjectIsAMBS

ObjectIsAMBS is a utility function to do the IsA check with passing the class name as string. This allows to check a variant with class names coming from a variable.

ObjectIsAMBS(o as object, ClassName as string) as boolean

Returns false in case of object being nil.

// isa check at runtime based on class name
Var w As Variant = d1
Var b1 As Boolean = ObjectIsAMBS(w, "Dictionary")
Var b2 As Boolean = ObjectIsAMBS(w, "Pair")

If you run this, b1 is true and b2 is false, if w contains a dictionary object.

ArrayIsAMBS

Next you may want to apply the IsA check to an array. In ArrayIsAMBS function the plugin walks over array entries and checks the first object for being of the type of that class.

ArrayIsAMBS(v as variant, ClassName as string) as boolean

Here is a sample code snippet:

// and isa check for array by checking first element
Var va As Variant = d
Var b3 As Boolean = ArrayIsAMBS(va, "Dictionary")
Var b4 As Boolean = ArrayIsAMBS(va, "Pair")

Returns false in case of variant being nil, not an object array or all values being nil.

GetVariantAsDictionaryArrayMBS

The GetVariantAsDictionaryArrayMBS specialized variant of GetVariantArrayMBS to return an array of Dictionary:

GetVariantAsDictionaryArrayMBS(v as variant) as Dictionary()

Here is a sample code snippet:

// now let the plugin cast back to a dictionary array
Var da() As Dictionary = GetVariantAsDictionaryArrayMBS(va)
			
Var vv() As Variant
vv.add New Dictionary
vv.add New pair(1,2)
			
// this raises exception due to pair
Var da2() As Dictionary = GetVariantAsDictionaryArrayMBS(vv)

Enjoy these utility functions and use them. And the best: You don’t even need a license since these functions are free to use!

9 Likes

Thank you for this post!

MBS has so many features it can get overwhelming and in my own apps I often find out (usually months later) that I have spent a great deal of time replicating functionality that my MBS license already includes.

While the MBS documentation is quite thorough there’s so much of it that it’s hard to keep track of everything all the classes can do.

Posts like this are greatly appreciated!

10 Likes