I like using a fake, unique value to represent nil in cases where I want to stream changes somewhere (like sharing table indices to clients). Only problem, I cannot normally represent those changes since nil removes keys altogether. Using a string is fine, but it creates an unnecessary edge case, and I run by Murphy’s Law.
Tables work perfectly, since they’re objects!
local NULL = {}
Due to the nature of tables, the equals == operator will only return true in the expression NULL == NULL; it’s an entirely unique value, different from any other value. Just like nil.
I then hook a couple metamethods with a proxy table to use Lua’s nil and my NULL seamlessly:
local p = newproxy(true)
local t = {}
local mt = getmetatable(p)
function mt.__index(self, index)
local v = t[index]
if v == NULL then
return nil
else
return v
end
end
function mt.__newindex(self, index, value)
t[index] = value == nil and NULL or value
end
As for serializing this to a DataStore, unfortunately JSON doesn’t have this functionality. You’ll have to use trivially null values (like -1, or empty string) but that opens some ambiguity.