Liaison avec __index
Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 7 sur 70.
Vous avez une table prototype avec des propriétés et des méthodes, mais comment faire en sorte qu'un nouvel objet l'utilise réellement ? La réponse réside dans la métaméthode __index.
Lorsque vous accédez à une clé qui n'existe pas dans une table, Lua renvoie normalement nil. Cependant, si la table possède une métatable avec un champ __index, Lua ira chercher à cet endroit à la place. En configurant __index pour qu'il pointe vers votre prototype, toutes les clés manquantes sont automatiquement trouvées dans le prototype :
local Dog = {
species = "Canis familiaris",
legs = 4
}
function Dog:bark()
print("Woof!")
end
-- Créer une instance vide
local myDog = {}
-- Le lier au prototype
setmetatable(myDog, { __index = Dog })
print(myDog.species) -- Résultat : Canis familiaris
myDog:bark() -- Résultat : Woof!La table myDog est complètement vide, pourtant l'accès à myDog.species fonctionne. Lorsque Lua ne trouve pas species dans myDog, il vérifie le __index de la métatable et le trouve dans Dog.
C'est le fondement de la programmation orientée objet en Lua. L'instance peut avoir ses propres données uniques, tandis que le comportement partagé réside dans le prototype. Dans la leçon suivante, vous apprendrez comment encapsuler ce modèle dans une fonction constructeur propre.
Défi
FacileMettons maintenant la métaméthode __index en pratique ! Vous allez créer un prototype et y lier une instance, permettant à l'instance d'accéder à des propriétés et des méthodes qu'elle ne possède pas directement.
Vous organiserez votre code sur deux fichiers :
Robot.lua: Définissez une table prototypeRobotavec :- Un champ
modeldéfini sur"RX-100" - Un champ
batteryLeveldéfini sur100 - Une méthode
:status()qui affiche l'état actuel du robot
- Un champ
main.lua: Importez le module Robot, puis créez une table d'instance vide et liez-la au prototype Robot en utilisantsetmetatableavec__index. Cela permet à votre instance vide d'accéder à tout ce qui provient du prototype.
Vous recevrez une entrée : un nom à attribuer à votre instance de robot.
Après avoir lié l'instance au prototype :
- Attribuez le nom reçu en entrée au champ
namede votre instance (cela devient unique à l'instance) - Appelez la méthode
:status()sur votre instance
Votre méthode :status() doit afficher le texte dans ce format exact :
[name] ([model]) - Battery: [batteryLevel]%Par exemple, si l'entrée est Sparky, la sortie doit être :
Sparky (RX-100) - Battery: 100%Remarquez comment l'instance possède son propre name, mais accède à model et batteryLevel à partir du prototype via le lien __index.
Aide-mémoire
La métaméthode __index permet aux objets d'hériter des propriétés et des méthodes d'une table prototype.
Lorsque vous accédez à une clé qui n'existe pas dans une table, Lua vérifie si la table possède une métatable avec un champ __index. Si c'est le cas, Lua recherche la clé dans la table spécifiée par __index.
Pour l'ier une instance à un prototype :
local Prototype = {
property = "value"
}
function Prototype:method()
print("Method called")
end
-- Create an instance
local instance = {}
-- Link to prototype using __index
setmetatable(instance, { __index = Prototype })
-- Access prototype properties and methods
print(instance.property) -- Output: value
instance:method() -- Output: Method calledLa table d'instance peut être vide, tout en pouvant accéder à toutes les propriétés et méthodes du prototype. L'instance peut également avoir ses propres propriétés uniques qui remplacent ou étendent le prototype.
Ce modèle est le fondement de la programmation orientée objet en Lua, où les instances partagent le comportement d'un prototype tout en conservant leurs propres données uniques.
Essayez vous-même
-- Lire l'entrée
local name = io.read()
-- Charger le module Robot
local Robot = require('Robot')
-- TODO: Créer une table d'instance vide
-- TODO: Lier l'instance au prototype Robot en utilisant setmetatable avec __index
-- TODO: Assigner le nom saisi au champ name de votre instance
-- TODO: Appeler la méthode :status() sur votre instance
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Le concept de « self »
Tables avec fonctions« self » expliciteLa syntaxe avec deux-pointsPoint vs deux-pointsRécapitulatif - Point mobile4Projet : Banque numérique
Configuration du projetMéthode de dépôt7Polymorphisme et Redéfinition
Redéfinition de méthodesAppeler des méthodes parentesDuck TypingInterface communeVérification du typeRécapitulatif - Rôles des employés10Projet : Gestionnaire de formes
Configuration du projetClasse Rectangle2Modèle de prototype de classe
Le concept de prototypeLiaison avec __indexLe constructeur :new()Initialisation des attributsInstances indépendantesRécapitulatif - Usine de voitures5Surcharge d'opérateurs en POO
Additionner des objetsSoustraire des objetsConcaténer des objetsComparer des objets (<, >)Récapitulatif - Calculs de portefeuille8Encapsulation
Conventions de nommageClosures pour la confidentialitéAccès via les ClosuresTables en lecture seuleLogique de validationRécapitulatif - Coffre-fort sécurisé11Patrons de conception (Lite)
Fonctions FactoryTable SingletonPatron IteratorObserver (Écouteur)Récapitulatif - Logger Factory3État et comportement des objets
Variables d'instanceMéthodes GetterMéthodes SetterPropriétés calculéesFormatage de chaînesVérifications d'égalitéRécapitulatif - Note de l'étudiant6Bases de l'héritage
Mise en place de l'héritageHériter des méthodesÉtendre le constructeurAjouter des méthodes enfantsPartagé vs UniqueRécapitulatif - Hiérarchie des formes