I’m trying to make two classes, one is Town, and the another is TownPlotManager.
Consider the following three scripts:
-- TownPlotManager code (module)
local TownPlotManager = {}
TownPlotManager.__index = TownPlotManager
function TownPlotManager.new(townPlotManager)
local self = townPlotManager
setmetatable(self, TownPlotManager)
return self
end
function TownPlotManager:RenderPlots()
-- more code here
end
--defaultTownDataModule (module)
local Town = require(script.Town)
local TownPlotManager = require(script.TownPlotManager) --
return Town.new{
TownPlotManager = TownPlotManager.new() -- args here
}
--TownDataLoader (script)
local defaultTownDataModule = require(game.ServerScriptService.defaultTownDataModule)
local userTownData = defaultTownDataModule
game.Players.PlayerAdded:Connect(function()
userTownData.PlotManager:RenderPlots()
end)
But when I try to call the :RenderPlots() method, i get an error from the ouput, saying that the method wasn’t found. I think that, when I call require(defaultTownData), the metatable get lost and it cannot find the :RenderPlots method.
Is there any way to make an object’s replica, keeping its metatable?
In the TownPlotManager module, you’re using .new() instead of :new(), which means that you’re making it a private function to that class. Because of this, in the defaultTownDataModule when you call TownPlotManager.new(), you’re not able to access the .new() function because it is private to the TownPlotManager script, essentially you cannot access that function from there.
Not sure what’s happening, because I can access the Town.TownPlotManager’s functions in the defaultTownDataModule. But when the table gets returned to TownDataLoader, it loses its metatable. Is it because of the require() function or something?
You seem to return what Town.new returns, not the table it self, its very likely that Town.new just returns something else.
local Town = require(script.Town)
local TownPlotManager = require(script.TownPlotManager) --
return Town.new{
TownPlotManager = TownPlotManager.new() -- args here
}
Perhaps you meant to do
local TownPlotManager = require(script.TownPlotManager)
return {
TownPlotManager = TownPlotManager.new() -- args here
}
The Town.new function has the same template as TownPlotManager.new, an basic OOP object.
function Town:new(town)
self = town
setmetatable(self, Town)
return self
end
So, the Town.new{TownPlotManager = TownPlotManager.new()} returns an town object with a TownPlotManager.new inside. The problem is, in the defaultTownDataModule, I can access the its returned object with functions, but in TownDataLoader I can’t.
I think that when I require() the module, the returned data loses its metatable. Not sure what’s happening.