Question

I'd like to create a simple mock table that would tell me what was tried to be called from it.

My first try was:

local function capture(table, key)
    print("call to " .. tostring(table) .. " with key " .. tostring(key))
    return key
end

function getMock()
    mock = {}
    mt = { __index = capture }
    setmetatable(mock, mt)

    return mock
end

Now calling this with

t = getMock()
t.foo

prints as I expected:

call to table: 002BB188 with key foo

but trying to call:

t.foo("bar")

gives:

call to table: 002BB188 with key foo
lua: test.lua:6: attempt to call field 'foo' (a string value)

Now I have two questions:

  1. How to avoid the exception, ie. what am I doing wrong?
  2. How to catch the method argument too ("bar" in this case)?
Was it helpful?

Solution

You need to return a function from the __index handler, not a string:

local function capture(table, key, rest)
    return function(...)
               local args = {...}
               print(string.format("call to %s with key %s and arg[1] %s",
                                   tostring(table), tostring(key),
                                   tostring(args[1])))
           end
end

-- call to table: 0x7fef5b40e310 with key foo and arg[1] nil
-- call to table: 0x7fef5b40e310 with key foo and arg[1] bar

You're getting an error because it's trying to call the result, but it's currently the key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top