Passing Strings as Arguments to use as Variable Names?

Hey everyone! I’ve run into a problem and I’m hoping you can lend some input. I’ve constructed a module that keeps track of players and stores them in one of three tables: Lobby, when they join the game; Team1 when the round starts and players are chosen for Team1, and the same for Team2. For example, when a player joins the game, this code activates:

In a server script:

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
local PlayerManager = require(game:GetService("ServerScriptService").Modules:WaitForChild("PlayerManager"))
PlayerManager.Insert("Lobby", Player)
end)

In the module script:

function PlayerManager.Insert(tableName, Player)
	if tableName == "Lobby" then
		table.insert(Lobby, Player)
	end
--etc for the other tables.
end

This code works just fine how it’s written, and it stores everything how it should. However, with all the other functions and variables involved that I didn’t include in this snippet of code, the code gets unnecessarily long and complicated. I would like the module to accomplish this…

function PlayerManager.Insert(tableName, Player)
	table.insert(tableName, Player)
end

…as this would cut down a lot of the code and would make it more efficient. I would essentially be passing the name of the table through the module function’s argument so that the name of the table can be used wherever it needs to be within the function. But alas, running it this way gives me a bad argument error (table expected - got string).

Am I approaching this from the wrong angle or is there a way this could be accomplished? Any help would be appreciated!

What is the “tableName” variable. From the error it looks like when you call the function you don’t call it with the table, but instead with a string.

Whenever I need to add, remove or just get the value from a certain table, I’d like to pass the name of that table through the function so that the module can choose what table to affect. In this case, tableName would be Lobby since I want to add to the Lobby table. In other example, I might want to add a player to a different table using the insert function within the module, so I’d pass down that table name instead. It’s a little confusing but I hope you get what I mean.

You can do this with metatables:

local LobbyTable = {
	"Player1",
	"Player2"
}

------------------------------------
------------------------------------
local Cache = {}
local function SetName(Table, Name)
	setmetatable(Table, {
		__tostring = function()
			return Name
		end,
		__index = function(i)
			return rawget(Table, i)
		end,
		__newindex = function(i, v)
			rawset(Table, i, v)
		end
	})
	Cache[Name] = Table
end

local function Insert(Name, ...)
	local Table = Cache[Name]
	if Table then
		table.insert(Table, ...)
	end
end

local function Remove(Name, Index)
	local Table = Cache[Name]
	if Table then
		table.remove(Table, Index)
	end
end
------------------------------------
------------------------------------
-- You would have to set all your tables' names with SetName
SetName(LobbyTable, "Lobby")

print(LobbyTable) -- Lobby
print(LobbyTable[2]) -- Player2
LobbyTable[2] = "Player222222"
print(LobbyTable[2]) -- Player222222
Remove("Lobby", 2)
print(LobbyTable[2]) -- nil
Insert("Lobby", "Inserted Player")
print(LobbyTable[2]) -- Inserted Player

If I’m understanding you correctly, you could just put Lobby, Team1, and Team2
into a table, say table foo and then simply do:

local tableName = "Lobby" -- Lobby for example.
table.insert( foo[tableName], Player )

Thanks for the responses, everyone! Club_Moo was right. I just needed to place all the tables into a dictionary - that allowed me to reference each table using their name.