Menu
Coddy logo textTech

Equality Checks

Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 17 of 70.

You've seen how __tostring controls how an object displays itself. Another useful metamethod is __eq, which defines when two objects should be considered equal using the == operator.

By default, comparing two tables with == checks if they're the exact same table in memory. Two separate objects with identical data will return false:

local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2)  -- Output: false (different tables)

With __eq, you can define your own equality logic. In a class, you add it just like __tostring—as a function in the class table. For equality to work, both objects must share the same metatable:

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

Now two User objects are considered equal if they share the same ID, regardless of other fields:

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)

This pattern is valuable when objects represent real-world entities with unique identifiers—comparing database records, game entities, or any objects where identity matters more than memory location.

challenge icon

Challenge

Easy

Let's build a Product class that can determine if two products are the same item—even when they're stored in completely different tables! In retail systems, products often have unique SKU codes (Stock Keeping Units), and two products should be considered equal if they share the same SKU, regardless of other details like price changes.

You'll organize your code across two files:

  • Product.lua: Define your Product class with the standard prototype pattern. Each product should store a sku (the unique identifier) and a name. Implement the __eq metamethod so that two products are considered equal when they have the same SKU—the name doesn't matter for equality.
  • main.lua: Require your Product module and create several product instances. Compare them using the == operator to see your custom equality logic in action.

Your Product class should include:

  • A :new(sku, name) constructor
  • A :getInfo() method that returns a string in the format: [sku]: [name]
  • The __eq metamethod that compares products by their SKU

You will receive six inputs:

  1. SKU for the first product
  2. Name for the first product
  3. SKU for the second product
  4. Name for the second product
  5. SKU for the third product
  6. Name for the third product

In your main file, create three products using the provided inputs, then print:

  1. The info for each product (three lines)
  2. The result of comparing product 1 with product 2
  3. The result of comparing product 1 with product 3

For example, if the inputs are ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789, and Keyboard, the output should be:

ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
false

Notice how the first two products are equal (same SKU) even though their names differ—this is exactly how real inventory systems track products through name changes and updates!

Cheat sheet

The __eq metamethod defines custom equality logic for objects using the == operator.

By default, comparing two tables checks if they're the same table in memory:

local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2)  -- Output: false (different tables)

To define custom equality, add __eq as a function in the class table. Both objects must share the same metatable:

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

Now objects are equal based on your custom logic:

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)

Try it yourself

-- Require the Product module
local Product = require('Product')

-- Read inputs
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: Create three Product instances using the inputs

-- TODO: Print the info for each product (three lines)

-- TODO: Print the result of comparing product 1 with product 2

-- TODO: Print the result of comparing product 1 with product 3
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming