2 votes

Remplacer la fonction uniquement pour une instance particulière en LUA

Je ne recherche pas vraiment une réponse sur la façon de faire quelque chose, mais j'ai trouvé comment le faire, et je souhaite obtenir plus d'informations. J'espère que ce genre de question est OK ici. Puisque je viens de découvrir le code d'un jeu sur lequel je travaille, je n'ai aucune idée de ce que je devrais chercher sur Google.

En Lua, je peux avoir par exemple:

Account = {balance = 0}
function Account.withdraw (v)
     self.balance = self.balance - v
end

Je peux avoir (dans un autre fichier lua)

function Account.withdrawBetter (v)
    if self.balance > v then 
      self.balance = self.balance - v
    end

.... -- quelque part dans une fonction, avec une instance de Account: a1.withdraw = a1.withdrawBetter `

Quel est le nom de cette "technique" pour que je puisse trouver plus d'informations à ce sujet (éventuelles pièges, considérations de performance par rapport au remplacement / écrasement, etc.)? Notez que je ne modifie que le withdraw pour l'instance particulière (a1), pas pour chaque instance de Account.

Question bonus: Y a-t-il d'autres langages de programmation orientés objet avec une telle fonctionnalité?

Merci

1voto

DarkWiiPlayer Points 1396

OO en Lua

Tout d'abord, il convient de souligner que Lua n'implémente pas la Programmation Orientée Objet; il n'a pas de concept d'objets, de classes, d'héritage, etc.

Si vous souhaitez OOP en Lua, vous devez l'implémenter vous-même. Habituellement, cela se fait en créant une table agissant comme une "classe", stockant les "méthodes d'instance", qui ne sont en réalité que des fonctions qui acceptent l'instance comme premier argument.

L'héritage est alors réalisé en ayant le "constructeur" (également une fonction) créer une nouvelle table et définir sa métatable sur une avec un champ __index pointant vers la table de classe. Lors de l'indexation de l'"instance" avec une clé qu'elle ne possède pas, elle cherchera alors cette clé dans la classe à la place.

En d'autres termes, une table d'"instance" peut ne pas avoir de fonctions du tout, mais en indexant celle-ci avec, par exemple, "withdraw", elle essayera simplement d'indexer la classe à la place.

Maintenant, si nous prenons une seule table d'"instance" et y ajoutons un champ withdraw, Lua verra qu'elle possède ce champ et ne cherchera pas dans la classe. Vous pourriez dire que cette valeur écrase celle de la table de classe.

Quel est le nom de cette "technique"?

Elle n'en a pas vraiment, mais vous devriez certainement vous intéresser aux métatables.

Dans les langages qui soutiennent ce genre de chose, comme en Ruby (voir ci-dessous), cela se fait souvent avec des classes singleton, ce qui signifie qu'elles n'ont qu'une seule instance.

Considérations de performance

L'indexation des tables, y compris des métatables, prend un certain temps. Si Lua trouve une méthode dans la table d'instance, alors c'est une seule recherche de table; si ce n'est pas le cas, il doit d'abord obtenir la métatable et indexer celle-ci à la place, et si elle ne l'a pas non plus et a sa propre métatable, la chaîne continue ainsi.

En d'autres termes, c'est en fait plus rapide. Cela utilise un peu plus d'espace, mais pas vraiment beaucoup (techniquement cela pourrait être beaucoup, mais vous ne devriez vraiment pas vous en inquiéter. Néanmoins, vous pouvez lire à ce sujet ici, si vous le souhaitez).

D'autres langages de programmation oo avec une telle fonctionnalité?

Oui, beaucoup. Ruby en est un bon exemple, où vous pouvez faire quelque chose comme

array1 = [1, 2, 3]
array2 = [4, 5, 6]

def array1.foo
  puts 'bar'
end

array1.foo # affiche 'bar'
array2.foo # lève une `NoMethodError`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X