I don’t want this to happen. I want to access the function itself because I’m wrapping things in metatables and I don’t want to have to write a special case for every possible member function, I just want to pass all of the arguments through a vararg.
workspace.FindFirstChild(workspace, a, b) should work the same as workspace:FindFirstChild(a, b) and shouldn’t error.
local instance=game.ReplicatedStorage.Instance
local build=game.ReplicatedStorage.Build
local function unwrap(v)
if type(v)=="table"and v.obj then
return v.obj
else
return v
end
end
local __eq=function(a,b)return a.obj==b.obj end
local function wrap(obj)
if typeof(obj)~="Instance"then return obj end
return setmetatable({
Clone=function()return wrap(build.Get:InvokeServer(obj,"Clone"))end,
Destroy=function()build:FireServer(obj,"Destroy")end,
BreakJoints=function()obj:BreakJoints()end,
MakeJoints=function()obj:MakeJoints()end,
GetChildren=function()
local t=obj:GetChildren()
for k,v in pairs(t)do t[k]=wrap(v)end
return t
end,
IsA=function(self,name)return obj:IsA(name)end,
FindFirstChild=function(self,...)return obj:FindFirstChild(...)end,
GetModelSize=function()return obj:GetModelSize()end,
GetModelCFrame=function()return obj:GetModelCFrame()end,
FindPartsInRegion3WithIgnoreList=function(self,...)return obj:FindPartsInRegion3WithIgnoreList(...)end,
Resize=function(self,...)return obj:Resize(...)end,
TranslateBy=function(self,...)return obj:TranslateBy(...)end,
MoveTo=function(self,...)return obj:MoveTo(...)end,
obj=obj
},{
__index=function(t,k)return wrap(obj[k])end,
__newindex=function(t,k,v)
v=unwrap(v)
obj[k]=v
build:FireServer(obj,k,v)
end,
__eq=__eq
})
end
return setmetatable({wrap=wrap,unwrap=unwrap},{__call=function(_,classname,parent)
return wrap(instance:InvokeServer(classname,unwrap(parent)))
end})
It would be a lot nicer if I didn’t need to add things like GetModelSize as a special case.
I’m not getting a stack traceback that points to the wrapper. table: 2F7E1A58 table 17:36:45.416 - Expected ':' not '.' calling member function FindFirstChild 17:36:45.417 - Stack Begin 17:36:45.417 - Script 'Players.Player1.PlayerGui.Control', Line 1681
print(obj,typeof(obj))
if not obj or obj.Locked or obj:FindFirstChild("Lock")then
I’m trying to do this in the wrapper instead
__index=function(_,k)
if type(k)=="function"then
return function(_,...)
local t={obj[k](obj,...)}
for k,v in pairs(t)do t[k]=wrap(v)end
return unpack(t)
end
else
return wrap(obj[k])
end
end,
edit: it was because type(k) is a string, it should be type(obj[k])
It’s a misleading error. Maybe you could change the feature request to ask for something more obvious: bad argument #1 to Instance.FindFirstChild (Instance expected; got {type})
I don’t think there’s much we can do here. I don’t believe our engine is aware of the syntax which was used to call the method: all it knows is that the first argument is not an instance and the usual suspect in that case is that the method was called using the “.” syntax instead of “:”
The error handler’s job isn’t to make uninformed guesses if it doesn’t have that info. It should report what it knows about the problem (bad arg type) and stop there.
That’s what it reported originally, but it’s confusing because many scripters don’t understand that when a method is invoked with the colon syntax, the first argument is the object on which the method was called, not the first in the argument list.