Vérifications d'égalité
Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 17 sur 70.
Vous avez vu comment __tostring contrôle la façon dont un objet s'affiche. Une autre métaméthode utile est __eq, qui définit quand deux objets doivent être considérés comme égaux en utilisant l'opérateur ==.
Par défaut, comparer deux tables avec == vérifie s'il s'agit de la même table en mémoire. Deux objets distincts avec des données identiques retourneront false :
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Sortie : false (tables différentes)Avec __eq, vous pouvez définir votre propre logique d'égalité. Dans une classe, vous l'ajoutez tout comme __tostring—en tant que fonction dans la table de classe. Pour que l'égalité fonctionne, les deux objets doivent partager la même métatable :
local User = {}
User.__index = User
function User:new(id, name)
local instance = {}
setmetatable(instance, self)
instance.id = id
instance.name = name
return instance
end
function User:__eq(other)
return self.id == other.id
endDésormais, deux objets User sont considérés comme égaux s'ils partagent le même ID, quels que soient les autres champs :
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Sortie : true (même ID)
print(u1 == u3) -- Sortie : false (IDs différents)Ce patron est précieux lorsque les objets représentent des entités du monde réel avec des identifiants uniques — comparer des enregistrements de base de données, des entités de jeu, ou n'importe quels objets où l'identité importe plus que l'emplacement en mémoire.
Défi
FacileConstruisons une classe Product capable de déterminer si deux produits sont le même article, même s'ils sont stockés dans des tables complètement différentes ! Dans les systèmes de vente au détail, les produits ont souvent des codes SKU (Stock Keeping Units) uniques, et deux produits doivent être considérés comme égaux s'ils partagent le même SKU, quels que soient les autres détails comme les changements de prix.
Vous organiserez votre code sur deux fichiers :
Product.lua: Définissez votre classeProductavec le modèle de prototype standard. Chaque produit doit stocker unsku(l'identifiant unique) et unname. Implémentez la métaméthode__eqafin que deux produits soient considérés comme égaux lorsqu'ils ont le même SKU — le nom n'importe pas pour l'égalité.main.lua: Importez votre module Product et créez plusieurs instances de produits. Comparez-les à l'aide de l'opérateur==pour voir votre logique d'égalité personnalisée en action.
Votre classe Product doit inclure :
- Un constructeur
:new(sku, name) - Une méthode
:getInfo()qui renvoie une chaîne de caractères au format :[sku]: [name] - La métaméthode
__eqqui compare les produits par leur SKU
Vous recevrez six entrées :
- SKU pour le premier produit
- Nom pour le premier produit
- SKU pour le deuxième produit
- Nom pour le deuxième produit
- SKU pour le troisième produit
- Nom pour le troisième produit
Dans votre fichier principal, créez trois produits à l'aide des entrées fournies, puis affichez :
- Les informations pour chaque produit (trois lignes)
- Le résultat de la comparaison du produit 1 avec le produit 2
- Le résultat de la comparaison du produit 1 avec le produit 3
Par exemple, si les entrées sont ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789, et Keyboard, la sortie devrait être :
ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
falseRemarquez comment les deux premiers produits sont égaux (même SKU) même si leurs noms diffèrent — c'est exactement ainsi que les systèmes d'inventaire réels suivent les produits à travers les changements de nom et les mises à jour !
Aide-mémoire
La métaméthode __eq définit une logique d'égalité personnalisée pour les objets utilisant l'opérateur ==.
Par défaut, la comparaison de deux tables vérifie s'il s'agit de la même table en mémoire :
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Résultat : false (tables différentes)Pour définir une égalité personnalisée, ajoutez __eq en tant que fonction dans la table de classe. Les deux objets doivent partager la même métatable :
local User = {}
User.__index = User
function User:new(id, name)
local instance = {}
setmetatable(instance, self)
instance.id = id
instance.name = name
return instance
end
function User:__eq(other)
return self.id == other.id
endDésormais, les objets sont égaux selon votre logique personnalisée :
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Résultat : true (même ID)
print(u1 == u3) -- Résultat : false (IDs différents)Essayez vous-même
-- Charger le module Product
local Product = require('Product')
-- Lire les entrées
local sku1 = io.read()
local name1 = io.read()
local sku2 = io.read()
local name2 = io.read()
local sku3 = io.read()
local name3 = io.read()
-- TODO : Créer trois instances de Product en utilisant les entrées
-- TODO : Afficher les informations pour chaque produit (trois lignes)
-- TODO : Afficher le résultat de la comparaison du produit 1 avec le produit 2
-- TODO : Afficher le résultat de la comparaison du produit 1 avec le produit 3
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