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.

P#62615 2019-03-06 15:51

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.

P#62617 2019-03-06 16:05

@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.

P#62621 2019-03-06 17:11 ( Edited 2019-03-06 17:12)

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.

P#62650 2019-03-07 08:41 ( Edited 2019-03-09 23:58)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 08:16:13 | 0.011s | Q:16