rawequal
rawequal(value1, value2) rawequal checks whether two values are exactly the same object in memory, bypassing any custom __eq metamethod. When you need to compare identity rather than value equality, this function is what you reach for.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
value1 | any | Yes | First value to compare |
value2 | any | Yes | Second value to compare |
rawequal returns true if value1 and value2 are identical objects (the same reference), and false otherwise. Unlike the == operator, it never invokes the __eq metamethod.
How It Differs From the == Operator
The == operator lets objects define their own equality behavior through the __eq metamethod. Two tables that are structurally identical but stored in different memory locations are considered unequal by == unless their __eq metamethod says otherwise. rawequal ignores metamethods entirely and checks whether the two values are the exact same object.
local a = {x = 1, y = 2}
local b = {x = 1, y = 2}
print(a == b) -- false (different objects, same contents)
print(rawequal(a, b)) -- false (they are different objects)
print(rawequal(a, a)) -- true (same object compared to itself)
This distinction matters most when working with tables as keys, caching systems, or any code that relies on object identity rather than value equality.
Comparing Tables Used as Keys
If you use a table as a table key, Lua compares those keys by identity. rawequal reflects this exact behavior, letting you check whether two keys are the same object.
local key = {"important", "key"}
local cache = {}
cache[key] = "stored value"
print(cache[key]) -- "stored value"
print(rawequal(cache[key], "stored value")) -- false (comparing value, not key)
When iterating over a table’s raw keys with next, rawequal is useful for checking whether a particular key object is present.
Avoiding Infinite Recursion in __eq
When you define a custom __eq metamethod that compares objects, calling rawequal inside that metamethod avoids the risk of infinite recursion if the comparison logic itself involves equality checks.
local function deepEqual(a, b)
if rawequal(a, b) then
return true -- same object, skip further comparison
end
-- ... comparison logic follows
return false
end
Comparing Primitives
rawequal works on all Lua types, including primitives. For numbers, strings, booleans, and nil, its behavior is identical to the == operator because these types do not have metamethods.
print(rawequal(1, 1)) -- true
print(rawequal("hello", "hello")) -- true
print(rawequal(nil, nil)) -- true
print(rawequal(true, false)) -- false
This makes rawequal useful as a general-purpose identity check that works uniformly across all types without needing to think about whether a type has custom equality behavior.
When to Use rawequal
Reach for rawequal when:
- You are implementing a custom
__eqmetamethod and need an identity check without triggering recursion - You are using tables as keys and need to verify that a key object is the exact same reference
- You want to confirm whether two values are the same object, not just equal in value
- You are building caching or interning systems where object identity matters
For value-based equality comparisons, use the == operator instead.
See Also
- next — iterate raw table keys without triggering metamethods
- rawget — read a table value without invoking
__index - rawset — write a table value without invoking
__newindex - lua-metatables — learn how
__eqand other metamethods work