lua-users home
lua-l archive

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


2009/11/26 Sebastian Wolff <sw@allmech.tuwien.ac.at>:
> I am pretty new to Lua and do have only experience wrapping C libraries
> using SWIG and luabind. Both are great tools. Now I have a problem where I
> have to write custom binding code and where I do not have any idea how to
> solve it:
>
> I want to write __index and __newindex methods which accept multiple data
> types as a key, eg. I like to use
>
>  object[0] = number; object[{1,2}] = number; etc.
>
> The thing is: the bindings of "object" have been created using one of the
> mentioned wrappers which do not support such an extended way of keys. What I
> want to do is to change the __index and __newindex methods after the actual
> registration of my class. I already found out how this could be done in Lua:
>
> function myown_index_method(table,key)
>  if (type(key) == "number") then
>   -- do something  elseif (... other types, eg. tables ...)
>   ...
>  else
>   return __oldindex(table,key)
>  end
> end
>
> local metaarray = getmetatable(MyClass())
> __oldindex = metaarray.__index
> metaarray.__index = myown_index_method(table,key)
>
> (analogously for __newindex)
>
> The problem is: I would like to implement this on C level for performance.
> Now I know how to write the new __index and __newindex methods in C.
>
> But what I do not know is:
> (1) How to call the original __index/__newindex methods from their new C
> replacements? Particularly I do not want to create global Lua variables such
> as '__oldindex' in the example. Maybe a C function pointer?

Your new metamethods are closures, and as such they have an
environment, and upvalues, even if implemented in C. Therefore you can
save a reference to the previous metamethod in one of these places.

> (2) How to set the __index/__newindex to the new methods? I think I could
> register them manually in their own scope and then set them using a Lua
> script such as the above. But then, again, I would waste the namespace.
>
> Does anyone have a simple idea how to solve this?

You can use a Lua script such as the one you propose, but instead of
making the new functions accessible in a global variables, you can
pass them as parameters to the script. To pass them from C, push the
functions on the stack before calling the script, and pass appropriate
arguments to lua_call. From within the script, to access the
parameters passed when the script was called you have to use the three
dots "...". You would simply prefix the script with a line or two like
:

local myown_index_method,myown_newindex_method = ...