Log In  


In order to save on some tokens, I put configuration number values into a string and then parsed that string. I then tried to use one of the values as a table key and it barfed on me.

Turns out, even though math functions recognize a string number as a number, using it as a table key will fail. You need to convert that string number into a integer for it work as a table key. My solution was to just add zero to number and it turned out okay.

t={"apple","orange","line"}
a="1"

printh(a+10) -- good, returns 11 (integer)
printh(t[a]) -- bad, returns FALSE

a+=0
printh(t[a]) -- good, returns "apple" as expected

All in all, it makes sense but I had never come across this before somehow. But seems kind of weird that Lua will let you be lazy with numbers for math but not for other things.



Tonum() may be what you need.
https://pico-8.fandom.com/wiki/Tonum
I think that it is called automatically when you do math on a string. My guess at least.


@morningtoast
I think it might help to keep in mind that, in Lua, any type (excluding nil) can be a key in a table: number, string, table, or even a function. So there's no way the interpreter would be able to assume you wanted to implicitly convert a string to a number in that case.


Yep, that's the answer. Arithmetic can only be done on numbers, so Lua will assume you want to convert it to a number and coerce it for you. (If you think about it, the same thing happens if you try to print a number or concatenate a string with a number; the number will silently be coerced into a string.) Table keys are not restricted on type, so Lua can't assume anything.

You can, of course, do the conversion yourself in the table's metatable.

t={"apple","orange","line"}
a="1"

t.__index=function(self,key)
 local k=tonum(key)
 if k>0 and k<=#self then -- this is needed since we don't have rawget()
  return self[k]
 else
  return nil
end
setmetatable(t,t)

printh(t[a]) -- good, prints "apple"

Sidenote: I do think it's a little weird that printh(nil) prints "false" and not "[nil]" like print(nil) does.

Edit: I forgot that we need to take care of non-valid numerical indices ourselves (so we don't get stuck in an infinite lookup loop), since we don't have rawget() in pico-8.



[Please log in to post a comment]