In Roblox, each tables have a memory address, which gets thrown into console when I attempt to print it:
print({})
-- 09:31:13.289 table: 0x132b12145a4ab545 - Studio
I can also get this memory address as a string by calling the tostring() function on a table:
tabl = {}
print(tostring(tabl)) -- 09:31:13.289 table: 0x132b12145a4ab545 - Studio
print(typeof(tostring(tabl))) -- 09:31:13.290 string - Studio
However, if I were to set the __tostring metamethod to the table, I am no longer able to get the memory address of it by converting it into a string or printing it into console:
tabl = {}
setmetatable(tabl, { __tostring = function() return "i love yana" end })
print(tostring(tabl)) -- 09:31:13.289 i love yana - Studio
print(tabl) -- 09:31:13.290 i love yana - Studio
Is there any way for me to get the memory address of the table with the __tostring metamethod set? And without modifying or removing the __tostring metamethod?
When you use print on the table lua automatically converts it to a string which is why it still prints “I love yana” as tostring is automatically called. Since there’s no way to override lua’s print conversion, im not aware of any ways to achieve your goal. Sry
Often i find metatables to be unnecessary in my work, so my experiences with them are lacking. However, you could potentially remove all unwanted information from the returned string, I’m not sure if you wanted the contents or the memory address, but you could easily remove one or the other.
I’d suggest looping through the contents of the table to do so. If you wanted the address, perhaps string.gsub and remove all of matching contents of the table to replace with “(empty)”. Then, you should just have the address.
Vice versa, you wanted just the contents? string.split or another better method (I cant recall which to use, to be honest) and then take the side with the contents to keep.
.__tostring overrides any functionality that tostring() would’ve had on tables.
You also can’t just call tostring() in your metamethod definition either, otherwise you get a stack overflow error.
An alternative would be to just store the memory address inside your table first, before setting its metatable.
When you set the metatable of the table, you’re not changing the identity of the table, so the memory address for that table is always valid.
The crucial part here though, is to get the memory address using tostring() BEFORE you override that table’s metamethod.
Sadly there’s no other clean way to do this - not unless you have access to the underlying C code that Luau runs on.
An example to get you started:
local mt = {
__tostring = function(t)
return "test"
end
}
local e = {}
e[1] = tostring(e)
print(e == setmetatable(e, mt))
-- This returns true, meaning the table WITHOUT the metatable is the same as the table WITH.
-- This proves that the memory address hasn't changed before and after setting its metatable.
setmetatable(e, mt)
for _, v in e do
print(v) -- At some point, should return an index with the memory address of the base table.
end
Feel free to wrap this in a function if it’s for your convenience.
Im not sure if this solution will work for you but you could create a seperate function that temporarly sets the metatable to nil and then get the memory address by using tostring.
local function getmemaddr(t): string
local temp = getmetatable(t)
setmetatable(t, nil)
local addr = tostring(t)
setmetatable(t, temp)
return addr
end
tbl = {}
setmetatable(tbl, {
__tostring =
function(self)
return "i love yana"
end
})
print(tbl) --> i love yana
print(getmemaddr(tbl)) --> table: 0x..