I have two module scripts (Client - Side) and I want to send the metatable of Module1 to Module2 with all the functions.
Further explanation:
Module 1
local Module = {} Module.__index = Module
local Module2 = Path_To_Module
Module.New = function(self)
local table = {Money = 79, Gold = 3}
for _,i in pairs(self) do table[_] = i end
return setmetatable(table, Module)
end
function Module:AddOre()
return “Test”
end
function Module:Send()
Module2.New(self):Print()
end
return Module
Module 2
local Module = {} Module.__index = Module
Module.New = function(self)
self.Diamonds = 69
return setmetatables(self, Module)
end
function Module:Print()
print(self.Diamonds, self.Gold, self:AddOre())
end
return Module
So I want to call module1 like: Module.New({Coal = 12, Iron = 0})
So now inside module1 Metatable it should have Coal, Iron, Money, Gold and with I call Module1:Send() , it should add this Metatable to Module2 Including the function in module1 AddOre
I get that, but why do you need to do this? What’s the use case? I’m just trying to figure out how to answer your question.
Because metatables are just tables. You can send them in a function parameter like normal:
local function PrintMetatable(t)
local m = getmetatable(t)
if m then
for k, v in pairs(m) do
print(k, v)
end
end
end
local t = {1, 2, 3}
PrintMetatable(t) --> nothing
local m = {__index = "test"}
setmetatable(t, m)
PrintMetatable(t) --> __index test
But I don’t think that’s really what you’re asking, so I’m asking at a high level what you’re trying to do.
Not to sound like a broken record, but why? This is a really weird thing to want to do, and I suspect there’s a better solution. You’re using the idea of modules and OOP in a very non-standard way, and it probably bite you later on.
Once more: why are you trying to do this? Is this a mining game? What do these modules represent?
I’m sorry for being so pedantic, I’m really trying to help you answer this, but the question is very hard to answer without more context.
At the very least, give example code with how you would even call these modules and what the expected output would be.
I’ve explained my goals several times throughout this topic, and I mean it doesn’t provide any importance knowing what in trying to use this for, isn’t the devforum for advice or solutions to your problems?, not interrogations
They’re just trying to help, because without explaining why you’re doing this, it looks like you’re using metatables in a weird way that can be avoided. If you responded to their questions without getting defensive, they could’ve found a much much simpler solution.
If anything you could’ve just said you’re not comfortable sharing why and that would’ve saved you about 3 replies.
Sorry, but it’s not that I’m comfortable sharing, it’s just that I told them what I wanted to achieve, but that keep stating that it’s a weird way of doing it
I’m not sure if I quite understand you, but if you wanted Module2 to inherit all of Module’s functions, you can loop through every element inside of Module, and insert it into Module2 if it is a function.
I’ve re-named Module to Module2 to discern the obvious differences between modules.
Module2.New = function(self)
for k,v in pairs (Module) do
if typeof(v) == "function" then
Module2[k] = v
end
end
Yeah, that what I’m trying to do, but unfortunately this doesn’t work either, I’ve tried it.
the functions in module1 are called with ”:” so adding each function to the meta in module2 won’t work. (Or at least that’s my discussion, for its failure) thank you for coming to my Ted talk
I gotta interrogate you because you keep saying “what”, not “why”.
Anyways, I’ll give it a shot.
The properties (Diamonds, Money, Gold) are in the table objects, not the metatables.
The functions (AddOre, Send, Print) are in the metatables Module1 and Module2.
So if you want Module2 to inherit functions from Module1, you can set the metatable for Module2 to be an instance of Module1 itself. Something like this:
-- Module1
local BaseClass = {}
BaseClass.__index = BaseClass
function BaseClass.new(prop)
local self = {
Property = prop or "default"
}
setmetatable(self, BaseClass)
return self
end
function BaseClass:Print()
print("BaseClass:Print", self.Property)
end
function BaseClass:PrintMore()
print("BaseClass:PrintMore", self.Property)
end
-- Module2, inherits from Module1
local ChildClass = {}
function ChildClass.new(parent)
local self = {}
return setmetatable(self, {
__index = function(t, k)
-- lookup in ChildClass first, or else the parent instance
return ChildClass[k] or parent[k]
end}
)
end
function ChildClass:PrintMore()
print("ChildClass:PrintMore", self.Property)
end
-- no extra metatable for ChildClass because we make a new one in the constructor
-- tests
-- create an BaseClass
local baseInstance = BaseClass.new()
baseInstance:Print() --> BaseClass:Print default
baseInstance:PrintMore() --> BaseClass:PrintMore default
-- create a ChildClass from that instance
local childInstance = ChildClass.new(baseInstance)
childInstance:Print() --> BaseClass:Print default
childInstance:PrintMore() --> ChildClass:PrintMore default
-- modify base instance, affects child
baseInstance.Property = "modified"
baseInstance:Print() --> BaseClass:Print modified
baseInstance:PrintMore() --> BaseClass:PrintMore modified
childInstance:Print() --> BaseClass:Print modified
childInstance:PrintMore() --> ChildClass:PrintMore modified
-- modify child instance, doesn't affect base
childInstance.Property = "modified again"
baseInstance:Print() --> BaseClass:Print modified (UNCHANGED)
baseInstance:PrintMore() --> BaseClass:PrintMore modified (UNCHANGED)
childInstance:Print() --> BaseClass:Print modified again (CHANGED)
childInstance:PrintMore() --> ChildClass:PrintMore modified again (CHANGED)
This is likely because your code has errors, I was able to successfully test it.
: is syntantical sugar for this: Module.Function(Module).
In your 2nd module, you were using setmetatables instead of setmetatable.
local Module2
local Module = {}
Module.__index = Module
Module.New = function(self)
local table = {Money = 79, Gold = 3}
return setmetatable(table, Module)
end
function Module:AddOre()
return "Test"
end
function Module:Send()
Module2.New(self):Print()
end
Module2 = {}
Module2.__index = Module
Module2.New = function(self)
for k,v in pairs (Module) do
if typeof(v) == "function" then
Module2[k] = v
end
end
self.Diamonds = 69
return setmetatable(self, Module)
end
function Module2:Print()
print(self.Diamonds, self.Gold, self:AddOre())
end
Module.New({Coal = 12, Iron = 0})
Module2.New({})
print(Module2:AddOre())
Additionally, in the example above, the __index metamethod still points to Module1 instead of Module2 (the memory addresses correspond with each other):
I hope this helps.
Again as previously stated, there are better ways on inheriting modules, this code base simply caters to your usecase.
My code didn’t contain any prominent errors, if my reply was stated as “setmetatables” instead of “setmetatable” then it’s probably just a typo, taking in to consideration that I wrote the reply and code on my phone, and wasn’t pasted from an physical script in my game.