4
int lua_isstring (lua_State *L, int index);

This function returns 1 if the value at the given acceptable index is a string or a number (which is always convertible to a string), and 0 otherwise. (Source)

Is there a (more elegant) way to really proof if the given string really is a string and not a number in Lua? This function makes absolutely no sense to me!

My first idea is to additionally examine the string-length with

 `if(string.len(String) > 1) {/* this must be a string */}`

... but that does not feel so good.

user1511417
  • 1,880
  • 3
  • 20
  • 41
  • Are you coding in Lua or C (i.e, using Lua API)? Why do you think this functions makes no sense? Why do you think `string.len(String) <= 1` could work? – Yu Hao Sep 29 '15 at 14:43
  • Lua and C++. It makes no sense, because it would return 1 if the checked string in Lua is actually = 4 or any other number. `string.len(...` could help, because a real string is usually longer than 1 or 2 characters. – user1511417 Sep 29 '15 at 14:53
  • 1
    `if( lua_type( L, index ) == LUA_TSTRING ) ...`. Lua converts numbers to strings and number-like strings to numbers for convenience, so `lua_isstring()` (and `lua_isnumber()`) is necessary if you want to do the same in your own API. – siffiejoe Sep 29 '15 at 14:59
  • @user1511417: `string.len()` won't help. A "real string" can be of any length. – Keith Thompson Sep 29 '15 at 15:18

2 Answers2

3

You can replace

lua_isstring(L, i)

which returns true for either a string or a number by

lua_type(L, i) == LUA_TSTRING

which yields true only for an actual string.

Similarly,

lua_isnumber(L, i)

returns true either for a number or for a string that can be converted to a number; if you want more strict checking, you can replace this with

lua_type(L, i) == LUA_TNUMBER

(I've written wrapper functions, lua_isstring_strict() and lua_isnumber_strict().)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

This function makes absolutely no sense to me!

It makes sense in light of Lua's coercion rules. Any function that accepts a string should also accept a number, converting that number to a string. That's just how the language semantics are defined. The way lua_isstring and lua_tostring work allow you automatically implement those semantics in your C bindings with no additional effort.

If you don't like those semantics and want to disable automation conversion between string and number, you can define LUA_NOCVTS2N and/or LUA_NOCVTN2S in your build. In particular, if you define LUA_NOCVTN2S, lua_isstring will return false for numbers.

Mud
  • 28,277
  • 11
  • 59
  • 92
  • Or you can use `lua_type()` and avoid modify and recompile Lua itself. – Keith Thompson Sep 29 '15 at 18:51
  • @Mud: Thanks for that hint! – user1511417 Sep 29 '15 at 19:14
  • @KeithThompson Your answer already covers that. My point is that you generally should *not* be checking for *only* strings in contexts that expect strings, because Lua semantics are [defined to accept a number in those contexts](http://www.lua.org/manual/5.3/manual.html#3.4.3). If you're hosting the interpreter, you can choose to disable type conversion. If you're not hosting the interpreter, then programmers expect be able to rely on standard Lua semantics and you should not violate those expectations. Using `isstring` and `tostring` automatically supports the correct, default semantics. – Mud Sep 29 '15 at 19:23
  • My point is that *if* you don't want the usual automatic coercions, IMHO using `lua_type()` is a better approach than rebuilding Lua itself to change the usual semantics of `lua_isstring` and `lua_tostring`. – Keith Thompson Sep 29 '15 at 19:28
  • @KeithThompson You already said that. You've shown how to bypass coercion on a per-instance basis (trivially discovered by looking at the source; I use `ttisstring` myself). My post is adding two additional bits of information: (1) in general this is a bad practice, because it violates the semantics of the language, and (2) if you're hosting the interpreter, there's a built-in mechanism for disabling coercion entirely. – Mud Sep 29 '15 at 19:33