Self not passing due to __index

Currently working on metatables, when I noticed any time I try to call a function, self isnt passed to said function.

Now I looked it up, and what it said was that it sends self in the form of the table it was directly called from, so in this case my proxy table (or what I call Constructor). I confirmed this but putting values inside of the proxy, and printing self.

So my question is how can I make it send self as the DataTable (or what I call Container)


Metatable:

setmetatable(Constructor, {
	__index = function(_, Key:string)
		if Container[Key] and not (Key:sub(1,1) == '_') then
			return Container[Key] -- This is the main point of interest, as this is what returns the function from container. 
		elseif Container:get(Key) then
			return Container:get(Key)
		end
	end,
	
	__newindex = function() return end
})

The function in Container:

local Container = {
	
	_Groups = {},
	
	-- Creates a New Group of Enum Types.
	new = function(self, Key:string) : EnumGroup?
		print(self) -- Prints the Constructor Table.
		
		-- // Container //
		local EnumGroup:EnumGroup = {}
		
		print(Key)
		print(self._Groups)
		self._Groups[Key] = EnumGroup
		
		return EnumGroup 
	end,
	
	-- Attempts to Find an Existing Enum Group.
	get = function(self, Key:string) : EnumGroup?
		return self._Groups[Key]
	end,
}

Me calling the functions:

local Custom = require(Module)

local Group = Module:new('GroupName')

Thanks in advanced!

when you do Constructor:new(), luau compiles that into Constructor.new(Constructor, …), therefore you could just return a bound function that passes Container as the first parameter instead of just passing the function directly

setmetatable(Constructor, {
	__index = function(_, Key:string)
		if Container[Key] and not (Key:sub(1,1) == '_') then
			return function(_, ...)
				return Container[Key](Container, ...)
			end
		elseif Container:get(Key) then
			return Container:get(Key)
		end
	end,
	
	__newindex = function() return end
})
1 Like

Cool this worked!

For anyone who sees this and gets curious on what I did, I just made this function:

local function CreateFunctionCaller(Table, Key)
	local function HolderFunction(...)
		local Sort = {...}
		table.remove(Sort, 1)
		
		return Table[Key](Table, unpack(Sort))
	end
	
	return HolderFunction
end
	__index = function(_, Key:string)
		if Container[Key] and not (Key:sub(1,1) == '_') then
			if typeof(Container[Key]) == 'function' then
				return CreateFunctionCaller(Container, Key) -- I use it here!
			else
				return Container[Key]
			end
		elseif Container:get(Key) then
			return Container:get(Key)
		end
	end,

then any time the __index function is called, and what the user is trying to access is a function, I just return what the CreateFunctionCaller makes.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.