Closed dpashkevich closed 11 years ago
Hi, thanks for taking the time to open an issue.
I think your requirement is too specific to be included in inspect as an extra parameter. However, I can give you a couple workarounds:
First, take into account, inspect will only print each table (or metatable) only once. If it finds a table again, it will print <1>, <2> and so on, taking very little space.
local obj1 = MyClass:new(...)
local obj2 = MyClass:new(...)
print(inspect({obj1=obj1, obj2=obj2}))
In the printed out format, obj1 will have the "full metatable info", but obj2 will just have a single line.
Extending this a bit more, you can make sure that the metatable information is not printed in any of your tables, if you print it out in advance. In other words:
print(inspect({MyClass, obj1=obj1, obj2=obj2}))
It will print MyClass
first, and then use <1>
for the metatable data of obj1
and obj2
, taking only 1 line of space. You will just have to scroll down a bit, but your objects will have (mostly) no metatable info.
There's a second way of doing this, which is temporarily modifying getmetatable to not return the metatables you don't want. I don't like this method very much, because it could leave getmetatable in a bad state if somehing goes wrong. Here's the idea:
local inspect = require 'inspect'
local ignoredMetatables = {MyClass1=1, MyClass2=1, MyClass3=1};
local oldGetmetatable = getmetatable
local selectiveGetmetatable = function(t)
var mt = oldGetmetatable(t)
if ignoredMetatables[mt] then return nil end
return mt
end
var selectiveInspect = function(...)
getmetatable = selectiveGetmetatable
local result = inspect(...)
getmetatable = oldGetmetatable
return result
end
That will create a specialized inspect function that will ignore the tables you include in ignoredMetatables
(the tables having them as metatables will appear to return nil).
I hope these two workarounds help you. For now, I will close down this issue.
Regards!
Thanks for quick response.
The first workaround doesn't look practical in my cases. A common scenario would be to output something in a function that's called repetitively, e.g.
function Cache:get(id)
local o = self.items[id]
print("Object retrieved from cache: ", inspect(o))
return o
end
So doing inspect({getmetatable(o), o})
doesn't help at all, I would have to "scroll down a bit"
anyway and that's exactly what I'm trying to avoid. The output can be quite long since in OOP-styled code the metatables can be quite big and link one to another ("inheritance chain").
The second approach looks more like what I was thinking of, only I think I can just temporarily delete a metatable for the inspected object instead of overriding the global getmetatable()
function:
function inspectOwn(t, d)
mt = getmetatable(t)
setmetatable(t, nil)
inspect(t,d)
setmetatable(t, mt)
end
I don't think my request is too specific but you're the boss :)
I'm repoening this in order to consider it again. I'm thinking about adding an options
param with an options.ignore
parameter to ignore certain tables.
On the new version of inspect
(2.0.0) you can use the filter
option to hide anything you want. For example:
local obj1 = MyClass:new(...)
local obj2 = MyClass:new(...)
print(inspect({obj1=obj1, obj2=obj2}, {filter = { MyClass} }))
The <metatable>
field will still appear, but its value will be <filtered>
.
{
obj1 = {
name = "Peter",
<metatable> = <filtered>
}
}
Sorry it took me so long to come around to fix this. Thanks again for reporting the issue, and regards!
Thanks! I'll check out the new version tomorrow. Are there any other highlights of 2.0.0?
You are right, of course - the changes are not obvious.
I have included a changelog file: https://github.com/kikito/inspect.lua/blob/master/CHANGELOG.md
This version is 2.0.0 because it is interface-breacking (the second parameter was a number before, but now it is a table). But for usual cases, inspect should work just like before.
(the second parameter was a number before, but now it is a table) I suggest supporting the older syntax because it's also shorter if one doesn't want to set other options. Created pull request #8, it's fairly trivial
I often find it unnecessary to include metatables in debug output. E.g. I want to inspect the own state of a class instance (defined via classlib or similar library) and don't care about all the "inherited" methods.
Having an option (perhaps as 3rd parameter to
inspect()
function) to exclude metatables would really unclutter debug output.