I just realized there is a better way to check the type of a variable (or expression, in general), than to check the string returned by `
type()` - and that is to try `
getInterface(var, <interface-needed>)`. I don't think i invented this wheel, since a search found it in one code example, although without explanation or justification in the documentation - nor in the forums. But much more often i have seen snippets like `... type(var) = "String" or type(var) = "roString" ...`. So here goes discussion on it.
Sometimes you get a structure that might contain mix of strings, numbers, booleans (say from JSON/XML parse)- and it is not clear which is what, so need to peek and act accordingly. You can do "type(expr)" and that returns the type as a string. String may vary, based on whether the value is boxed or not (e.g. "Boolean" vs "roBoolean", "String" vs "roString", "Float" vs "roFloat"). It gets egregious in the case of integers, where it may be "Integer", "roInt" or "roInteger" - and seems that at some point the return of boxed value was "roInteger" but later changed to "roInt", yet there are still corner cases where "roInteger" pops out. The thought of text returned changing bothers me.
The alternative approach is: ask the value if it supports particular interface we need, e.g. `getInterface(42, "roInt")`. If it returns something valid (non-invalid), it is the type we want. We can write thin wrappers around that and turn it to utility functions like so:
function isString(x):
return getInterface(x, "ifString") <> invalid
end function
function isInteger(x):
return getInterface(x, "ifInt") <> invalid
end function
function isFloat(x):
return getInterface(x, "ifFloat") <> invalid
end function
function isDouble(x):
return getInterface(x, "ifDouble") <> invalid
end function
function isBoolean(x):
return getInterface(x, "ifBoolean") <> invalid
end function
The check is so short, it does not really need to be pulled to function but if one want to have leeway to change their mind later (i.e. "i want to use type()=string here").
The use is kinda obvious but here is example:
BrightScript Debugger> ? isBoolean(false), isBoolean(7 < 1), isBoolean(5)
true true false
BrightScript Debugger> ? isFloat(1.2), isFloat(5#), isFloat("5")
true false false
BrightScript Debugger> ? isString(""), isString(invalid)
true false
There are some odds and ends to discuss, like performance (which is faster? should test) and there not being ifInvalid (there are 2 type()s, "Invalid" and "roInvalid").