I'm using metamethods for my "Number Instance" module to act like real numbers. Most of the metamethods are working fine, except for these three: __eq, __le, and __lt. They are scripted the same way with __concat, __add, __sub, __mul, __div, __mod, and __pow, but they won't work properly as expected. I tried printing them in a script and this is what they printed:
local NumberService = require(game:GetService("ReplicatedStorage"):WaitForChild("CustomServices")):GetService("NumberService")
local TestNumber = NumberService.new(50)
print("My number is " .. TestNumber) -- "My number is 50" (working) __concat
print(-TestNumber) -- -50 (working) __unm
print(TestNumber + 50) -- 100 (working) __add
print(60 - TestNumber) -- 10 (working) __sub
print(TestNumber * 2) -- 100 (working) __mul
print(50 / TestNumber) -- 1 (working) __div
print(TestNumber % 28) -- 22 (working) __mod
print(2 ^ TestNumber) -- 1125899906842624 (working) __pow
print(tostring(TestNumber)) -- "50" (working) __tostring
print(50 == TestNumber) -- false (not working) __eq
print(TestNumber < 60) -- attempt to compare table < number (not working) __lt
print(TestNumber > 60) -- attempt to compare table > number (not working) __lt
print(40 <= TestNumber) -- attempt to compare table <= number (not working) __le
print(TestNumber >= 40) -- attempt to compare table >= number (not working) __lt
print(#TestNumber) -- attempt to get length of a number value (working) __len
This is the expected output to the lines that are not working
print(50 == TestNumber) -- true
print(TestNumber < 60) -- true
print(TestNumber > 60) -- false
print(40 <= TestNumber) -- true
print(TestNumber >= 50) -- true
And this is the module script
newNumber.__index = NumberInstance
newNumber.__concat = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number .. b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number .. b
elseif not isNumberInstance1 and isNumberInstance2 then
return a .. b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a .. b
end
end
newNumber.__unm = function(self)
return -(self.Number)
end
newNumber.__add = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number + b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number + b
elseif not isNumberInstance1 and isNumberInstance2 then
return a + b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a + b
end
end
newNumber.__sub = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number - b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number - b
elseif not isNumberInstance1 and isNumberInstance2 then
return a - b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a - b
end
end
newNumber.__mul = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number * b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number * b
elseif not isNumberInstance1 and isNumberInstance2 then
return a * b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a * b
end
end
newNumber.__div = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number / b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number / b
elseif not isNumberInstance1 and isNumberInstance2 then
return a / b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a / b
end
end
newNumber.__mod = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number % b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number % b
elseif not isNumberInstance1 and isNumberInstance2 then
return a % b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a % b
end
end
newNumber.__pow = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number ^ b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number ^ b
elseif not isNumberInstance1 and isNumberInstance2 then
return a ^ b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a ^ b
end
end
newNumber.__tostring = function(self)
return tostring(self.Number)
end
newNumber.__eq = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number == b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number == b
elseif not isNumberInstance1 and isNumberInstance2 then
return a == b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a == b
end
end
newNumber.__lt = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number < b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number < b
elseif not isNumberInstance1 and isNumberInstance2 then
return a < b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a < b
end
end
newNumber.__le = function(a, b)
local isNumberInstance1 = typeof(a):lower() == "table" and a.Number ~= nil
local isNumberInstance2 = typeof(b):lower() == "table" and b.Number ~= nil
if isNumberInstance1 and isNumberInstance2 then
return a.Number <= b.Number
elseif isNumberInstance1 and not isNumberInstance2 then
return a.Number <= b
elseif not isNumberInstance1 and isNumberInstance2 then
return a <= b.Number
elseif not isNumberInstance1 and not isNumberInstance2 then
return a <= b
end
end
newNumber.__len = function(self)
error("attempt to get length of a number value", 0)
end
