7

I have a c function that is called from lua. The first parameter is a table. That table is abused as an input array of numbers to an underlying api. So right now my code looks like this:

int n = 0;
lua_pushnil ( L );
while ( lua_next ( L, 2 ) ) {
   n++;
   lua_pop ( L, 1 );
}
int *flat = alloca ( n * 4 );
lua_pushnil ( L );
int i = 0;
while ( lua_next(L,2) ) {
   flat[i++] = (int)lua_tonumber( L, -1 ); 
   lua_pop ( L, 1 );
}

I typed the code blind, so please forgive errors. Also no error checking. But the problem is that I have to do the while loop twice. Is there an easy way to avoid that? I want to optimize for the case where the input is good - a table of ints.

starmole
  • 4,974
  • 1
  • 28
  • 48
  • Normally, I'd downvote a question who's answer is found in the Lua docs. But considering that the function name is non-obvious, and that the obvious Google search failed to find it, I'll let it slide. – Nicol Bolas Sep 27 '12 at 08:46
  • 1
    Sorry for that, but lua seems to be especially hard to google. Add to that that there are many changes between 5.1 and 5.2. Don't get me wrong, I am learning a lot, but the reference manual is hard to search. For example earlier I spent a bit of time re-implementing luaL_checklong, just because I missed the right name. – starmole Sep 27 '12 at 09:31

1 Answers1

13

The function you're looking for is unintuitively named lua_objlen, or in Lua 5.2, lua_len (there is a lua_rawlen if you wish to avoid metamethod invocations). It serves many roles (though some, like the length of a string, aren't very useful when you can just use lua_tolstring to get the string and its length), so you should be familiar with it.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    One should note that this may not return the correct number when the table consists of something other than contiguous integers - see [this](http://stackoverflow.com/questions/652957/how-do-i-get-the-number-of-keys-in-a-hash-table-in-lua) and [this](http://stackoverflow.com/questions/2705793/how-to-get-number-of-entries-in-a-lua-table). – mtsvetkov Sep 27 '12 at 08:50
  • Actually it works as long as the table consists of contiguous things that are not nil, not only integers. In Lua [this is called a 'sequence'](http://www.lua.org/manual/5.2/manual.html#3.4.6). Note that in Lua 5.1 the definition was slightly different but the definition from Lua 5.2 is simpler. Also note that in Lua 5.2 lua_objlen has been renamed [lua_rawlen](http://www.lua.org/manual/5.2/manual.html#lua_rawlen) and does *not* respect the __len metamethod. – catwell Sep 27 '12 at 09:01
  • Thank you for the 5.2 update. I should have mentioned i am using 5.2. – starmole Sep 27 '12 at 09:22
  • 1
    @catwell: It wasn't renamed into `lua_rawlen`; it was *split* into two functions: `lua_len` and `lua_rawlen`, much as with `lua_gettable` vs. `lua_rawget`. One allows metamethods, the other does not. – Nicol Bolas Sep 27 '12 at 09:40
  • Yes, I meant that the equivalent of `lua_objlen` is `lua_rawlen` (does not care about `__len`). `lua_len` is a new function that (afaik) has no equivalent in 5.1 and corresponds to the `#` operator. – catwell Sep 27 '12 at 13:23