lua-users home
lua-l archive

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


On 6/29/07, John McKenna <john.mckenna@ubisoft.com> wrote:
Obviously, indexing a table will only get you one value.  Less
obviously, that's true even when there's an __index metamethod that
returns more than one result:

  mt = { __index = function() return 1, 2, 3 end }
  t = {}
  setmetatable( t, mt )
  a, b, c = t.test
  print( a, b, c )

gives "1   nil  nil".

We'd like to get multiple values("1  2  3").  Is that easy to do?

I've been poking at the source, and found some likely-looking functions.
Replacing the last parameter of the call to luaD_call() in callTMres()
with LUA_MULTRET is an obvious start.  Then I'll have to persuade
setobjs2s() to copy all values to the right place.  And then... I get
lost.  How does the VM know that luaV_gettable() only returns one value?
The rest of the stack is still full of callTMres()'s workings.


Why do we want multiple values?  We decided that the nicest interface to
our ugly C++ code is through properties (yes, there's an ex-Delphi
programmer on the team):

object.position = otherObject.position

ends up calling C++ functions to get and set the position.  Then someone
decided that the state of a controller button (we do console games) was
best expressed with two values: state (it has just been pressed, it is
still being pressed, it has just been released, etc) and pressure:

state, pressure = controller.button

These are the multiple values we want to return from __index.


change the source code a little
mt = { __index = function() return {1, 2, 3} end }
t = {}
setmetatable( t, mt )
a, b, c = unpack(t.test)
print( a, b, c )