Menu
Coddy logo textTech

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
end

Dé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.

challenge icon

Défi

Facile

Construisons 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 classe Product avec le modèle de prototype standard. Chaque produit doit stocker un sku (l'identifiant unique) et un name. Implémentez la métaméthode __eq afin 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 __eq qui compare les produits par leur SKU

Vous recevrez six entrées :

  1. SKU pour le premier produit
  2. Nom pour le premier produit
  3. SKU pour le deuxième produit
  4. Nom pour le deuxième produit
  5. SKU pour le troisième produit
  6. Nom pour le troisième produit

Dans votre fichier principal, créez trois produits à l'aide des entrées fournies, puis affichez :

  1. Les informations pour chaque produit (trois lignes)
  2. Le résultat de la comparaison du produit 1 avec le produit 2
  3. 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
false

Remarquez 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
end

Dé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
quiz iconTestez-vous

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