Hey developers! I’m new to Module scripts. I have been scripting for quite some time, just I haven’t used many module scripts for my projects…
What I want to do is have a function run when a variable is mentioned in the module list…
Right now I have this as my Module Script:
local function MakeEvent()
print("this is ran")
--This function would do other things like make instances etc.
return "this is a test"
end
local EventsToGive = {
["FlaggedMessageClient"] = MakeEvent() --MakeEvent is my function
}
return EventsToGive
And when I run this line:
local Events = require(PathToModuleScript)
MakeEvent() (Aka My function) runs… How can I make it so my function only runs when it is mentioned like this:
local Events = require(PathToModuleScript)
local Test = Events["FlaggedMessageClient"]
print(Test)
You could try using metatables to detect if a value has been indexed or newindexed(bascially adding a new key) (table only)
local function MakeEvent()
print("this is ran")
--This function would do other things like make instances etc.
return "this is a test"
end
local EventsToGive = {
["FlaggedMessageClient"] = "anythibg" -- :)
}
local mt = {
__index = function(t,i) -- returns Table and indexed (t[i])
MakeEvent()
end
__newindex = function(t,i,v) -- returns Table, indexed and value (t[i] = v)
MakeEvent()
end
-- add more metamethods down or add restrictions
}
setmetatable(EventsToGive,mt)
My system uses remote events / Bindable Events, in other words, MakeEvent() returns BindableEvent.Event or RemoteEvent.OnServerEvent or RemoteEvent.OnClientEvent…
Now this works all and well normally!
The issue is that this function Makes the event if it doesn’t exist, Or returns the event if it exists… In other words, I have a bunch of these Variables in the table, but I don’t want to run them unless they are called, to which when they are called, makes them / returns them.
The solution you have gave me would mess up the format. Is this a small issue? Yes, but it would be important to me as other creators would be using this module script…
Normally, a table will return a value of the indexed (ex, t[i] = 5)
so technically you don’t even need to do anything cause it will return t[“FlaggedMessageClient”]'s value(which is the remote event)
also you need a trigger to use the :Connect() trigger, unless if you miraculously did that part when running the function(maybe that is your problem? )
Well Table[“FlaggedMessageClient”] would equal RemoteEvent.OnClientEvent (in this case) which is a RBXConnection, or as you mention, a trigger, right? . (It doesn’t return the Remote event / Bindable event, but it returns a RBX connection from the event.)
The Event doesn’t exist Until MakeEvent() is called for the first time, to then it stays forever until the server dies.
Still reading about your first post and trying things out…
I’m having kinda this issue right now where I can detect when it is indexed, no clue how I can make it so Table["FlaggedMessageClient"] is actually the event… I tried a couple of things… But I have no clue what I’m doing so yea…
Module:
local EventsToGive = {
["FlaggedMessageClient"] = nil
}
local metaTable = {
__index = function(Table,Indexed)
print("Called")
EventsToGive[Indexed] = MakeEvent(Indexed) -- this is where I'm lost and don't know what to do..
end,
}
local Maintable = setmetatable(EventsToGive,metaTable)
return Maintable
My Test Script:
local Module = require(PathToModule)
Module.FlaggedMessageClient:Connect(function()
print("It worked!")
end)
I think all that needs changing in your code is this:
local EventsToGive = {
["FlaggedMessageClient"] = nil
}
local metaTable = {
__index = function(Table,Indexed)
print("Called")
EventsToGive[Indexed] = MakeEvent(Indexed)
return EventsToGive[Indexed] -- Just return the new event when it is created the first time
end
}
local Maintable = setmetatable(EventsToGive,metaTable)
return Maintable
There is a way to make this code more flexible too by making use of the Table argument:
local metaTable = {
__index = function(Table,Indexed)
print("Called")
Table[Indexed] = MakeEvent(Indexed)
return Table[Indexed] -- Just return the new event when it is created the first time
end
}
Which would allow you to have separate tables of events that make use of this one metatable.
Hey! I do want to say that it does work, so thank you! However there is 2 mini bugs that if possible, I would like fixed!
1. Whenever anything is indexed that is nil, it will fire this function as Seen on the docs. Is there a way where I can only fire my function when a value is true / false and not nil? Because module.ThisEqualsNil and module.ThisIsntInTheTableLOL will still fire off the function.
Current behavior: If Indexed Value is Nil, It will fire, if Value isn’t Nil, __Index won’t run at all
Wanted behavior: If Indexed Value is Nil or a Value that isn’t Boolen, It won’t fire, if Value is Boolen, function will fire
Edit: Fixed
This is a smaller issue, but is there a way I can tell luau Engine that the table Index Values, that they are a RBXScriptSignal reguarding their actual Value… Example with just one Variable:
local ExampleSignal : RBXScriptSignal = nil -- Even though it's nil, Luau Engine overrides and thinks it a RBXScriptSignal with the ": RBXScriptSignal"
ExampleSignal:Connect(function()
end)
and I need sometyhing like that but for a table like:
local EventsToGive = {
["FlaggedMessageClient"] = nil,
}
--This Doesn't work to my knowledge when trying it out
local EventsToGive = {
["FlaggedMessageClient"] : RBXScriptSignal = nil,
}