Comprobaciones de Igualdad
Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 17 de 70.
Has visto cómo __tostring controla cómo se muestra un objeto a sí mismo. Otro metamétodo útil es __eq, que define cuándo dos objetos deben considerarse iguales utilizando el operador ==.
Por defecto, comparar dos tablas con == comprueba si son exactamente la misma tabla en memoria. Dos objetos distintos con datos idénticos devolverán false:
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Salida: false (tablas diferentes)Con __eq, puedes definir tu propia lógica de igualdad. En una clase, lo añades igual que __tostring—como una función en la tabla de la clase. Para que la igualdad funcione, ambos objetos deben compartir la misma metatabla:
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
endAhora, dos objetos User se consideran iguales si comparten el mismo ID, independientemente de otros campos:
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Salida: true (mismo ID)
print(u1 == u3) -- Salida: false (IDs diferentes)Este patrón es valioso cuando los objetos representan entidades del mundo real con identificadores únicos: al comparar registros de bases de datos, entidades de juegos o cualquier objeto donde la identidad importa más que la ubicación en memoria.
Desafío
Fácil¡Vamos a construir una clase Product que pueda determinar si dos productos son el mismo artículo, incluso cuando están almacenados en tablas completamente diferentes! En los sistemas de venta al por menor, los productos suelen tener códigos SKU (Stock Keeping Units) únicos, y dos productos deben considerarse iguales si comparten el mismo SKU, independientemente de otros detalles como los cambios de precio.
Organizarás tu código en dos archivos:
Product.lua: Define tu claseProductcon el patrón de prototipo estándar. Cada producto debe almacenar unsku(el identificador único) y unname. Implementa el metamétodo__eqpara que dos productos se consideren iguales cuando tengan el mismo SKU; el nombre no importa para la igualdad.main.lua: Requiere tu módulo Product y crea varias instancias de productos. Compáralas usando el operador==para ver tu lógica de igualdad personalizada en acción.
Tu clase Product debe incluir:
- Un constructor
:new(sku, name) - Un método
:getInfo()que devuelva una cadena en el formato:[sku]: [name] - El metamétodo
__eqque compara productos por su SKU
Recibirás seis entradas:
- SKU para el primer producto
- Nombre para el primer producto
- SKU para el segundo producto
- Nombre para el segundo producto
- SKU para el tercer producto
- Nombre para el tercer producto
En tu archivo principal, crea tres productos usando las entradas proporcionadas, luego imprime:
- La información de cada producto (tres líneas)
- El resultado de comparar el producto 1 con el producto 2
- El resultado de comparar el producto 1 con el producto 3
Por ejemplo, si las entradas son ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789, y Keyboard, la salida debería ser:
ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
falseObserva cómo los dos primeros productos son iguales (mismo SKU) aunque sus nombres difieran; ¡así es exactamente como los sistemas de inventario reales rastrean los productos a través de cambios de nombre y actualizaciones!
Hoja de referencia
El metamétodo __eq define una lógica de igualdad personalizada para objetos utilizando el operador ==.
Por defecto, comparar dos tablas comprueba si son la misma tabla en memoria:
local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2) -- Output: false (different tables)Para definir una igualdad personalizada, añade __eq como una función en la tabla de la clase. Ambos objetos deben compartir la misma metatabla:
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
endAhora los objetos son iguales basándose en tu lógica personalizada:
local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")
print(u1 == u2) -- Output: true (same ID)
print(u1 == u3) -- Output: false (different IDs)Pruébalo tú mismo
-- Requerir el módulo Product
local Product = require('Product')
-- Leer entradas
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: Crear tres instancias de Product usando las entradas
-- TODO: Imprimir la información de cada producto (tres líneas)
-- TODO: Imprimir el resultado de comparar el producto 1 con el producto 2
-- TODO: Imprimir el resultado de comparar el producto 1 con el producto 3
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1El concepto de 'self'
Tablas con funciones'self' explícitoLa sintaxis de dos puntosPunto vs. dos puntosResumen - Punto en movimiento4Proyecto: Banco Digital
Configuración del proyectoMétodo de depósito2Patrón de prototipo de clase
El concepto de prototipoVinculación con __indexEl constructor :new()Inicialización de atributosInstancias independientesResumen - Fábrica de coches5Sobrecarga de operadores en POO
Sumar objetosRestar objetosConcatenar objetosComparar objetos (<, >)Resumen - Matemáticas de la billetera8Encapsulamiento
Convenciones de nomenclaturaClosures para privacidadAcceso mediante ClosuresTablas de solo lecturaLógica de validaciónResumen - Bóveda segura11Patrones de diseño (Lite)
Funciones FactoryTabla SingletonPatrón IteradorObserver (Listener)Resumen - Logger Factory3Estado y Comportamiento de los Objetos
Variables de InstanciaMétodos GetterMétodos SetterPropiedades CalculadasFormateo de StringsComprobaciones de IgualdadResumen - Calificación del Estudiante6Fundamentos de la herencia
Configuración de la herenciaHerencia de métodosExtender el constructorAñadir métodos hijosCompartido vs. ÚnicoResumen: Jerarquía de formas