Check for variable type in URScript

Is there a way to get back the type of a variable after it is declared? I would like to be able to verify that a value is of the correct type before assigning it to a variable so that if there is an issue I can catch the issue and handle it better then just having the code crash if we were to assign the wrong type of value to the variable.

1 Like

We don’t have perfect solution, but you could try using to_str(var), and then parse output with string manipulation functions.

Thanks for the suggestion, we are working on something and will post back when it’s “done”

Hi. @mbush!

did dou get it “done”?? its interesting!

Here is the code that we developed and have written tests around.

#Type definitions
local NUMBER = "number"
local STRING = "string"
local BOOL = "boolean"
local LIST = "list"
local POSE = "pose"
local NULL = ""
local LIST_OF_POSES = "listOfPoses"
local UNDEFINED = "undefined"

def typeOf(value):
  local valueString = to_str(value)
  if (valueString == "True" or valueString == "False"):
    return BOOL
  elif (isNumber(valueString)):
    return NUMBER
  elif (str_at(valueString, 0) == "[" and isList(valueString)):
    return LIST
  elif (str_at(valueString, 0) == "p" and isPose(valueString)):
    return POSE
  elif (isString(str_at(valueString, 0))):
    return STRING
  end
  return UNDEFINED
end

def isNumber(value):
  local valueIsNumber = True
  local j = 0
  if (str_at(value, 0) == "-"):
    value = str_sub(value, 1)
  end
  while (j < length(value) and valueIsNumber):
    local testValue = str_at(value, j)
    i = 0
    valueIsNumber = False
    while (i < 10 and not valueIsNumber):
      if (testValue == to_str(i) or testValue == "."):
        valueIsNumber = True
      end
      i = i + 1
    end
    j = j + 1
  end
  if (valueIsNumber):
    return True
  end
  return False
end

def isString(value):
  return True
end

def isPose(valueString):
  if isList(str_sub(valueString, 1)):
    return True
  end
  return False
end


def isList(valueString):
  local lengthOfString = length(valueString)
  if (lengthOfString > 2):
    if (str_at(valueString, 0) == "[" and str_at(valueString, lengthOfString - 1) == "]"):
      local firstComma = str_find(valueString, ",", 1)
      if (firstComma == -1):
        local firstIndex = str_sub(valueString, 1, lengthOfString - 2)
      else:
        local firstIndex = str_sub(valueString, 1, firstComma - 1)
      end
      if (typeOf(firstIndex) == NUMBER or typeOf(firstIndex) == BOOL):
        return True
      end
    end
  end
  return False
end

We have not really done much with the string type, basically assume the UR will puke on program execution of any undefined types and so if it’s not one of the initial types that we test for, we assume its a string or else the program would not play. If someone else can come up with a lightweight test for strings that is robust we would look at adding it to our code.

2 Likes

Great work!

A quick addition to add matrix type detection support for the typeOf(value) could be to add a case like this :

elif (str_at(valueString, 0) == "[" and str_at(valueString, 1) == "[" ):

Might be interesting to add a ListOfLists type and a ListofPoses type as well. I will take a look at that and possibly move this code over to a public github repo where you can access the code more easily.

1 Like

Sure! and it would also be nice to a method to get the size of the matrix.

And my quick solution will probably need an update if/when these types are added :wink:

1 Like