3

According to the Lua manual, setmetatable still works the same as in Lua 5.0. Yet for some reason, when I try this code in Lua 5.1.5 and 5.3.1, it appears that the metatable is not accessed:

ClassTable = {}
ClassTable.getString = function(self) 
  return self.x .. ""
end

inst = {}
setmetatable(inst, ClassTable)
inst.x = 7

--doens't work
assert(getmetatable(inst) == ClassTable)
print(inst:getString())

The first case works, however in the second case the I get the error which suggests that the metatable is not being used:

./lua: /test.lua:12: attempt to call method 'getString' (a nil value)
stack traceback:
    test.lua:12: in main chunk
    [C]: ?

This also has nothing to do with the method call operator ":" as even getting the value of the method doesn't go to the metatable.

print(inst.getString)
nil
stands2reason
  • 672
  • 2
  • 7
  • 18

1 Answers1

2

To make the table inst access the metatable you need to use the metamethod __index.

So you can correct the code by adding this line at the top below ClassTable.getString definition:

ClassTable.__index = ClassTable

Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table.

Rochet2
  • 1,146
  • 1
  • 8
  • 13
  • Setting __index in the instance object doesn't seem to work though. Does this mean __index is only checked in the metatable? – stands2reason Dec 13 '15 at 23:37
  • 1
    @stands2reason Yes. All metamethods need to be in the metatable. You may want to read through the reference about them because that is basically the first thing said about them: http://www.lua.org/manual/5.3/manual.html#2.4 – Rochet2 Dec 14 '15 at 00:28