'get the address of a lua object
When you print certain types in lua (such as functions and tables), you get the name of the type and an address, as below:
> tab = {}
> print(tab)
table: 0xaddress
I have created a simple class as below, and I would like to override the __tostring method similarly. How do I get the address of the object that I want to print?
Here's my class. I would like print(pair) to print out Pair: 0xaddress. Obviously this is a trivial example, but the concept is useful:
Pair = {}
Pair.__index = Pair
function Pair.create()
local p = {}
setmetatable(p, Pair)
p.x = 0
p.y = 0
return p
end
function Pair:getx()
return self.x
end
function Pair:gety()
return self.y
end
function Pair:sety(iny)
self.y=iny
end
function Pair:setx(inx)
self.x=inx
end
Solution 1:[1]
Here's a hokey way to do it:
Pair.__tostringx = function (p)
Pair.__tostring = nil
local s = "Pair " .. tostring(p)
Pair.__tostring = Pair.__tostringx
return s
end
Pair.__tostring = Pair.__tostringx
> print(p)
Pair table: 0x7fe469c1f900
You can do more string manipulation inside Pair.__tostringx to get the format you want, e.g., to remove "table".
Solution 2:[2]
I think that the __tostring() that prints table: 0xaddress isn't actually implemented in straight Lua. I looked around a bunch, but the only way I could think to do it isn't exactly what you were thinking. I added a function to the Pair class called toString that uses the default __tostring() to get the normal string, then takes out "table" and puts in "Pair".
function Pair:toString()
normalPrint = tostring(self)
return ("Pair:" .. normalPrint:sub(7))
end
pair = Pair.create()
print(pair:toString())
Then you call Pair:toString() to get the properly formatted output. You can't do this while overriding __tostring because you'll have a hard time accessing the super's __tostring, and if you call Pair's __tostring, a stack overflow occurs from the recursion.
Solution 3:[3]
Not the same syntax you used, but works: (However could be polished)
Pair = {}
Pair.address = string.gsub(tostring(Pair), "table:", "") --Gets the original address as a string.
local metas = {
__tostring = function(tab)
return "Pair:" .. tab.address
end
}
setmetatable(Pair, metas)
print(Pair) --Will print Pair: 0xaddress
Solution 4:[4]
You can use __name in Lua 5.3 or higher.
print(tostring(setmetatable({}, {__name = "Pair"})))
it prints:
Pair: 0x5575ef88cf50
Solution 5:[5]
local function f() end
local t = {}
print(f, t)
print(string.format("%p\t%p", f, t))
--[[
function: 0x8813c0 table: 0x881810
0x8813c0 0x881810
]]
Tested on https://www.lua.org/demo.html.
Solution 6:[6]
Try
function rawstr(t)
local mt = getmetatable(t)
local save_tostring
if mt and mt.__tostring then
save_tostring = mt.__tostring
mt.__tostring = nil
end
local raw = tostring(t)
if save_tostring then
mt.__tostring = save_tostring
end
return raw
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Doug Currie |
| Solution 2 | boztalay |
| Solution 3 | HackNoobLixo |
| Solution 4 | JE42 |
| Solution 5 | |
| Solution 6 | Mike Blyth |
