2012-02-01 1 views
4

J'utilise Lua comme langage de description de données pour mon application C++. J'ai un tas de classes C++ liées à Lua en utilisant SLB 2.0. J'ai des méthodes liées telles que 'SetPos' ou 'SetName'. Je spécifie la position ou le nom (par exemple) en utilisant une table avec des valeurs entrées comme 'pos' ou 'name'. Je veux être en mesure de prendre la clé, préfixer 'set', et appeler la méthode, si elle existe (il peut ne pas). Est-ce possible? Si oui, des suggestions?Can Lua prend en charge les appels de méthode insensible à la casse?

Je sais que je pourrais faire mes méthodes liées minuscules, mais je préfère les garder les mêmes que les méthodes auxquelles ils sont liés (ce qui peut être mon retour si). Je pourrais essayer de construire le nom de la méthode en fonction de mes normes de dénomination, mais l'insensibilité à la casse est moins sujette aux erreurs.

Je pense qu'il devrait être un morceau difficile de Lua qui pourrait résoudre ce problème en utilisant des métabalises, mais je n'ai pas été capable de le faire moi-même.

Des suggestions?

Merci!

+0

Je ne suis pas familier avec SLB. Avez-vous une table pleine de fonctions qui sont liées à votre C++? Il est certainement possible de faire ce que vous voulez si vous avez une table pleine de fonctions, car vous pouvez définir la méthode metatable '__index' pour faire une recherche insensible à la casse de votre table pour une méthode correspondante et la retourner. Cela dit, pourquoi avez-vous même besoin de cela? Les fonctions Lua en général sont sensibles à la casse, donc je ne vois aucun problème à laisser vos fonctions telles quelles. –

+2

Je suggérerais * fortement * d'adopter et de suivre une politique de cohérence où les noms sont exactement les mêmes (+/- le préfixe 'set') aux deux endroits. –

+0

La raison pour laquelle je veux être un peu laxiste avec le cas est que si je fais une erreur dans le cas, je ne connaîtrai pas le temps d'exécution. De toute évidence pas un spectacle, mais ce serait bien. Quant à savoir pourquoi je voudrais le faire en premier lieu, la raison en est que je veux prendre une variable (name = "blah") dans mon fichier lua (par exemple dans un tableau de définitions), et le mapper à un appel à une méthode (myObj.SetName ("blah")). –

Répondre

6

L'insensibilité à la casse n'est pas vraiment quelque chose que Lua gère. Toutes les recherches de table et les accès variables locaux sont des comparaisons de chaînes sensibles à la casse. La meilleure solution serait de simplement accepter que vous avez affaire à un système sensible à la casse, tout comme le C++, et y faire face. Cependant, si vous le voulez vraiment, vous pouvez le faire. Le plus simple serait de mettre chaque cas possible de permutation d'un nom dans votre table de fonction. Donc, votre table de fonction aurait ceci:

["setname"] = theFunction, 
["Setname"] = theFunction, 
["sEtname"] = theFunction, 
["SEtname"] = theFunction, 
... 

Vous pouvez d'automatiser ce cours avec une fonction qui prend chaque nom dans le tableau et reproduit ses données basées sur les permutations de cas.

Un mécanisme plus impliqué mais plus facile à utiliser serait d'utiliser les métaméthodes __index et __newindex ainsi que l'astuce de table vide.

function CreateCaseInsensitiveTable() 
    local metatbl = {} 

    function metatbl.__index(table, key) 
    if(type(key) == "string") then 
     key = key:lower() 
    end 

    return rawget(table, key) 
    end 

    function metatbl.__newindex(table, key, value) 
    if(type(key) == "string") then 
     key = key:lower() 
    end 

    rawset(table, key, value) 
    end 

    local ret = {} 
    setmetatable(ret, metatbl) 
    return ret 
end 

Au lieu de créer une table avec {}, vous créez la table avec cet appel de fonction. La table devrait normalement fonctionner normalement (bien que l'accès des membres soit légèrement plus lent).

+0

Merci. J'ai décidé de modifier SLB pour créer un alias en minuscule pour ma liaison de méthode. Je peux alors chercher ceci en utilisant __index dans ma classe et l'appeler en utilisant le formulaire 'funcName (objectInstance, methodName)'. Je ne veux que cette fonctionnalité pour sérialiser les données, donc je vais éviter de modifier les fonctions __index & __newindex pour le moment. –