2015-03-22 1 views
-1

J'ai un objet que je crée en utilisant la fonction suivantevariable fonction deepcopying donne des résultats inattendus

local function newObject(functionVariable) 
    ... 
    functionVariable = functionVariable or nop 
    ... 
    return setmetatable({ 
     ... 
     functionVariable   = functionVariable, 
     ... 
    }, Objectmt) 
end 

Quand je deepcopy cet objet en utilisant ce

local function deepcopy(t) 
    if t == nil then return nil end 

    if type(t) == 'table' then 
      local copy = {} 

      for k, v in pairs(t) do 
        copy[k] = deepcopy(v) 
      end 
      setmetatable(copy, deepcopy(getmetatable(t))) 
      return copy 
    else -- number, string, boolean, etc 
      return t 
    end 
end 

et la charge dans l'objet en utilisant ce

for k, v in pairs(state.objectsTable) do objectsTable[k] = v end 

La variable de fonction est totalement erronée. Ce n'est pas la fonction qui a été passée dans l'objet et donne des résultats inattendus

Répondre

2

Il y a beaucoup de choses qui pourraient mal se passer, et pas assez d'informations pour être sures. Cependant, il y a certaines choses que je peux voir qui pourraient être fausses avec votre copie, et une en particulier qui semble problématique.

Votre fonction deepcopy copie le métatable de l'objet:

-- snip... 
setmetatable(copy, deepcopy(getmetatable(t))) 
-- ... 

Cependant, il est une pratique assez courante pour les objets du même type pour partager la même métatable, et d'ailleurs, votre code semble faire ceci (bien que sans voir comment Objectmt est défini, ce n'est pas clair). Autre code peut alors, par exemple, déterminer si quelque chose est un objet en faisant:

function isObject(obj) 
    return getmetatable(obj)==Objectmt 
end 

Cela échouera pour votre copie, parce que le métatable n'est plus le même (même si elle a le même contenu).

Cela pourrait être résolu en ayant une version différente de deepcopy (ou modifier l'existant) de réutiliser le métatable:

-- snip... 
setmetatable(copy, getmetatable(t)) 
-- ... 

Si ce n'est pas le problème, sont quelques autres choses à considérer:

  • Votre fonction de copie profonde ne copie pas les clés de table. Dans certains cas, la copie des clés peut être importante, mais cela ne semble pas être le cas pour le code que vous avez montré.
  • Votre fonction de copie profonde ne copiera pas les fonctions. Cela peut être important si vous utilisez des fonctions avec des valeurs up mutables. Encore une fois, ce n'est pas le cas pour le code que vous avez montré.
  • Il est possible qu'il existe d'autres tables en dehors de la métabalise qui doivent être copiées par référence plutôt que par valeur. Pour savoir ce qui est approprié, vous devez comprendre la façon dont ils sont utilisés.
  • Il pourrait y avoir des données d'utilisateur ou d'autres types moins communs (par exemple des corépondions) qui sont actuellement copiés par référence et qui devraient être copiés par valeur. Certaines choses pourraient ne pas être copiables en valeur.
  • Il se peut qu'il y ait quelque chose dans les données que vous copiez qui ne devrait pas être copié du tout, par exemple, un identifiant unique.
  • Le problème peut ne pas être du tout avec la copie.