aoiee
aoiee

Reputation: 355

Lua check if a table is an 'instance'

Given a table, is there a way to check if it is an instance object of any class?

Assume all class definition looks like:

Class = {}
Class.__index = Class

function Class.new()
    return setmetatable({}, Class) -- returns an instance
end

Upvotes: 7

Views: 4096

Answers (2)

moteus
moteus

Reputation: 2235

I use just getmetatable function

if getmetatable(thing) == Class then

But if you use some type of inheritence then you can try this one

local A = {} A.__index = A
function A:new() return setmetatable({}, A) end
function A:foo() print('foo') end

local B = setmetatable({}, A) B.__index = B
function B:new() return setmetatable({}, B) end
function B:boo() print("boo") end

local function is_instance(o, class)
  while o do
    o = getmetatable(o)
    if class == o then return true end
  end
  return false
end

local a = A:new()
local b = B:new()

a:foo()
b:foo()
b:boo()

print(is_instance(a, A))
print(is_instance(a, B))
print(is_instance(b, B))
print(is_instance(b, A))

Upvotes: 6

Vlad
Vlad

Reputation: 5847

In theory you could read table's metatable with getmetatable(), and compare received table agains list of classes known to you.

But it means metatable shouldn't be protected (__metatable field is not set to something different, getmetatable() is not removed within sandbox, etc), and you should know all available classes.

If there some metatable set on a table, it doesn't mean that table is a part of class hierarchy, or class at all. It just might use metatables to solve its own tasks.

Upvotes: 3

Related Questions