test to see if two inputs are a number and not empty

lua
16,350

Solution 1

Your code breaks if first is a number and second is nil, since comparing a number to nil is an error. Here is a more correct version:

first = tonumber(frame.args[1])
second = tonumber(frame.args[2])

if second and first and (first <= second) then
  return math.random(first, second)
elseif first then
  return math.random(first)
else return math.random() end

However this code is very fragile: it doesn't check the type of arguments, and it doesn't make sure the numbers are integers either. Depending on what it's used for you may want to make it stricter. A really strict version would look like:

local is_int = function(n)
  return (type(n) == "number") and (math.floor(n) == n)
end

local first, second = frame.args[1], frame.args[2]

if first == nil then
  assert(second == nil)
  return math.random()
else
  assert(is_int(first))
  if second == nil then
    return math.random(first)
  else
    assert(is_int(second))
    return math.random(first,second)
  end
end

Of course you could also decide to return nil on unexpected input instead of using assertions...

Solution 2

If it's okay to accept a string that contains a number, tonumber(foo) will work, and will actually convert it to a "number" value internally. But if you need to know whether Lua considers it an actual number or not, rather than a string, use 'number' == type(foo) in your test conditions.

Share:
16,350

Related videos on Youtube

Bart Humphries
Author by

Bart Humphries

Updated on September 16, 2022

Comments

  • Bart Humphries
    Bart Humphries over 1 year

    I have a function which may be called with 0, 1, or 2 arguments. I want to test to see how many arguments were entered and whether they're actual numbers. Here's the code:

    first = tonumber(frame.args[1])
    second = tonumber(frame.args[2])
    
    if first then
      if first <= second then
        return math.random(first, second)
      end
    return math.random(first)
    end   
    return math.random()
    

    My thought is that if they aren't numbers (or are empty), then when I call tonumber() the variables will be false. The <= might be true if they're both NaN, but they had to go through "first" existing as a number, so they both have to be numbers and the comparison won't short circuit the if statement. If any if is failed, it'll just skip on down to the next valid return. Seem good? Anyone see any problems?