2017-07-19 1 views
1

Étant donné une table, existe-t-il un moyen de vérifier s'il s'agit d'un objet instance de n'importe quelle classe?Lua vérifie si une table est une 'instance'

On suppose toute définition de classe ressemble à:

Class = {} 
Class.__index = Class 

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

Répondre

2

En théorie, vous pouvez lire la métatable de table avec getmetatable() et comparer la liste agains de table reçues des classes connues de vous. Mais cela signifie que metatable ne doit pas être protégé (__metatable field n'est pas défini sur quelque chose de différent, getmetatable() n'est pas supprimé dans sandbox, etc), et vous devez connaître toutes les classes disponibles.

S'il existe un ensemble pouvant être mis en correspondance sur une table, cela ne signifie pas que la table fait partie de la hiérarchie de classe, ni la classe du tout. Il pourrait simplement utiliser des métabalises pour résoudre ses propres tâches.

+0

'debug.getmetatable' peut être utilisé dans ce cas. – moteus

1

J'utilise simplement la fonction getmetatable

if getmetatable(thing) == Class then 

Mais si vous utilisez un certain type de inheritence alors vous pouvez essayer celui-ci

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))