Say if I had a Userdata that I set the __metatable metamethod to a table. And a Userdata with the __metatable metamethod not set.

local lockedUserdata = newproxy(true)

local meta = getmetatable(lockedUserdata)

meta.theseFunctions = function() end
meta.areTheRealMethods = function() end

meta.__metatable = {
	theseFunctions = function() end,
	areTheFakeMethods = function() end
}

local unlockedUserdata = newproxy(true)

meta = getmetatable(unlockedUserdata)

meta.theseFunctions = function() end
meta.areTheRealMethods = function() end

In this case I can't think of a way to differentiate them (other then the variable name, obviously, but that is for example purposes).

Using getmetatable on ether will return a table.

> print("unlocked: ", getmetatable(unlockedUserdata)) print("locked: ", getmetatable(lockedUserdata))   unlocked: {                     ["areTheRealMethods"] = "function",                     ["theseFunctions"] = "function"                  } - Edit   locked: {                     ["areTheFakeMethods"] = "function",                     ["theseFunctions"] = "function"                  } - Edit

I cant pcall setmetatable because that will error for both, setmetatable always errors when inputted with a Userdata.

> print(pcall(setmetatable, unlockedUserdata), pcall(setmetatable, lockedUserdata)) - Studio false false invalid argument #1 to 'setmetatable' (table expected, got userdata) - Edit

Technically I could parse the error pcall returned to see what the cause of the error was. But I'm not too keen on parsing errors codes as they can change, making all my code outdated.

Any ideas?

4 comments

0

not certain so I'm commenting. since your first metatable is set to a metatable, your getmetatable(getmetatable(locked)) would be {} and getmetatable(getmetatable(unlocked)) would be nil, no? correct me, but unless it's a typo, you should be setting meta.__metatable, using __metatable alone won't work. getmetatable on the locked one should give you a blank, which you could also use?

0

if you don't want to rely on that, the only thing I can think of is something like meta.__metatable = setmetatable({_LOCKED = true}, {}) or setmetatable({}, {_LOCKED = true}), and check if _LOCKED exists.

0

@Speedmask I edited the question, I meant to use tables instead of metatables

0

in that case, aside from pcall, I'll have to stand by my locked solution. you'll need some identifier between both tables. otherwise if you are trying to restrict some methods, you can always just check if they exist before calling. that's all I can think of anyway, sorry :)