lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Interesting, Peter....

I'm impressed with your knowledge and "thought processes" with Lua...
Obviously you've done some serious stuff with it.

Curiously, I did think of having my __index function being a C function but
then I didn't want to have to write the hashing code to index into tables,
etc.

But you simply turn around and have lua handle the table indexing for me.
Very keen and worth considering.

Thx again,
Ando


> 
> Ando Sonenblick wrote:
>> I have a table (obviously a metatable that implements simple inheritance):
>> 
>> {
>>     __index = function(table, key)
>>         return  rawget(XMethods, key) or
>>                 rawget(YMethods, key) or
>>                 rawget(ZMethods, key) end
>> }
>> 
>> Now, is there a way (from C code) to traverse the table to extract out the
>> strings "XMethods", "YMethods" and "ZMethods" (without having to resort to
>> parsing the Lua source code)?
>> 
>> I'm hoping to implement an object inspector that will take and object and
>> digest it's metatable and display in a UI the contents of the "inherited"
>> tables, etc...
> 
> Hi Ando,
> 
> You could make your index event a C function with an upvalue that is a
> list of tables to search.  Then from C, you could retrieve the upvalue
> and find the names of the list elements in the table of globals.
> 
> This should give you some ideas:
> 
> print'hello'
> 
> one = { a=1,b=2,c=3 }
> two = { d=99 }
> three = function(t,i) print('did not find',i) return false end
> 
> print('one', one)
> print('two', two)
> print('three', three)
> 
> x = setmetatable({}, {__index = search{ one, two, three } })
> 
> print(x.a, x.b, x.c, x.d, x.it)
> 
> 
> function name(value)
>  for n,v in _G do
>    if value == v then return n end
>  end
> end
> 
> for i,e in ipairs(searchlist(x)) do print(name(e), e) end
> 
> 
> The output from this script is:
> 
> hello
> one     table: 0xa045d20
> two     table: 0xa0464a8
> three   function: 0xa045e78
> did not find    it
> 1       2       3       99      false
> one     table: 0xa045d20
> two     table: 0xa0464a8
> three   function: 0xa045e78
> 
> 
> where the search and searchlist functions are written in C like so:
> 
> 
> #include "lua.h"
> #include "lauxlib.h"
> 
> static int searcher (lua_State *L) {
>  int i=1;
>  do {
>    lua_settop(L, 2);
>    lua_rawgeti(L, lua_upvalueindex(1), i++);
>    if (lua_isnil(L, -1)) return 0;  /* end of search list */
>    if (lua_isfunction(L, -1)) {
>      lua_pushvalue(L, 1);  /* table */
>      lua_pushvalue(L, 2);  /* index */
>      lua_call(L, 2, 1);
>    } else if (lua_istable(L, -1) || lua_isuserdata(L, -1)) {
>      if (lua_rawequal(L, 1, -1)) continue;  /* ignore recursive tables */
>      lua_pushvalue(L, 2);  /* index */
>      lua_gettable(L, -2);
>    } else {
>      luaL_error(L, "search list item must be a function, table or
> userdata");
>    }
>  } while (lua_isnil(L, -1));
>  return 1;
> }
> 
> static int search (lua_State *L) {
>  luaL_checktype(L, 1, LUA_TTABLE);
>  lua_settop(L, 1);
>  lua_pushcclosure(L, searcher, 1);
>  return 1;
> }
> 
> static int searchlist (lua_State *L) {
>  if (!lua_getmetatable(L, 1)) return 0;  /* no metatable */
>  lua_pushliteral(L, "__index");
>  lua_gettable(L, -2);
>  if (lua_isnil(L, -1)) return 0;         /* no __index event */
>  if (!lua_iscfunction(L, -1)) return 0;  /* not a searcher function */
>  if (!lua_getupvalue(L, -1, 1)) return 0;  /* no upvalue */
>  if (!lua_istable(L, -1)) return 0;      /* upvalue not a table */
>  return 1;
> }
> 
> int search_register (lua_State *L) {
>  lua_register(L,"search", search);
>  lua_register(L,"searchlist", searchlist);
>  return 0;
> }
> 
> - Peter
> 

-----------------
SpriTec Software
www.spritec.com