2010-05-30 17 views
1

simple jeu Lua avec classe simple comme ceci:Lua instance de classe avec des tables imbriquées

creature = class({ 
name = "MONSTER BADDY!", 

stats = { power = 10, agility = 10, endurance = 10, filters = {} }, 

other_things = ... 
}) 

creatureA = creature.new() 

creatureB = creature.new() 

creatureA.name = "Frank" 

creatureB.name = "Zappa" 

creatureA.stats.agility = 20 

creatureB.stats.power = 12 

- bla bla bla

valeurs non de table sont propres à chaque cas, mais les valeurs de la table sont partagées entre toutes les instances et si je modifie une valeur stats.X dans une instance, toutes les autres instances voient la même table de statistiques.

Q1: Mon implémentation OO est-elle défectueuse? J'ai essayé LOOP et le même résultat s'est produit, y a-t-il un défaut fondamental dans ma logique?

Q2: Comment chaque instance de créature aurait-elle sa propre table de statistiques (et ses sous-tables)?

PS. Je ne peux pas aplatir ma table de classe car c'est un peu plus compliqué que l'exemple et d'autres parties du code sont simplifiées avec cette implémentation de table imbriquée.

+1

, vous n'avez pas besoin des parenthèses dans l'appel de fonction à la classe. class {} == class ({}). – Puppy

Répondre

0

Lors de la création d'un nouveau creature vous pouvez toujours créer une nouvelle table stats si vous ne voulez pas qu'il soit partagé.

creature = class({ 
    name = "MONSTER BADDY!", 
    stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }), 
    other_things = ... 
}) 

puissance, agilité, etc. serait passé comme arguments dans le constructeur de stats.

2

Il fonctionne comme ça parce que les instances de classe ont la table de classe définie comme __index dans leur métatable (bien, la plupart des implémentations fonctionnent de cette façon) Donc, si vous accédez creatureA.stats (et il ne peut pas trouver stats sur creatureA, tombe ainsi à __index) il renvoie creature.stats. Peut-être que vous devriez lire sur Lua 5.1 Reference Manual: Metatables

Vous ne pouvez pas déclarer des variables par instance dans le constructeur de la table de la classe (à moins que vous en profondeur tout copie de la table de classe à l'instance, ce qui serait assez cher)

Vous devrez le faire quelle que soit la fonction initialiseur votre implémentation de classe utilise:

creature = class 
{ 
    __init = function(self, ...) 
     self.stats = {power = 10, agility = 10, endurance = 10, filters = {}} 
    end, 
} 
3

class n'est pas une fonction standard dans Lua. Vous ne dites pas si vous l'avez emprunté à Roberto, vous avez roulé le vôtre, ou quoi. Mais je suppose que vous voulez changer la méthode new afin qu'il effectue une copie profonde du prototype au lieu d'une copie superficielle:

function deep_copy(v) 
    if type(v) == 'table' then 
    local u = { } 
    for k, v in pairs(v) do 
     u[k] = v 
    end 
    setmetatable(u, getmetatable(v)) 
    return u 
    else 
    return v 
    end 
end 

(Alert: Je n'ai pas essayé de compiler ce code, Laisse courir seul.)

0

Cette fonction de votre que l'appele class semble suspect. Je vais pour le code le plus simple possible. Voici un fichier de classe monstre. Rien d'extraordinaire et certaines personnes diraient qu'il manque un peu duveteux mais au moins je peux lire le code moi-même la semaine prochaine aussi.

-- Class object 

monster = {} 
monster.__index = monster 

-- Class methods 

function monster.new(name) 
    local o = {} 
    o.name = name 
    o.stats = {power = 10, agility = 10, endurance = 10, filters = {}} 
    setmetatable(o, monster) 
    return o 
end 

function monster:shout() 
    print('Aaaaaaa! My name is ' .. self.name .. '!') 
end 

Et est ici la sortie:

> lua 
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio 
> require 'monster' 
> m = monster.new('Katla') 
> m:shout() 
Aaaaaaa! My name is Katla!