Hello, I have an issue that seemed so simple to fix on paper, but i’ve been stuck trying to figure it out for a while now.
I’m basically trying to identify which script has fired the module function. I’ve seen posts suggesting using getfenv(2).script, but apparently it’s deprecated. So instead i’ve tried using debug.info as Roblox Studio has suggested:
local fs = debug.info(2, "s") -- using this to get the scripts ancestry
local dismantle = fs:split(".")
local ins = game
for i,v in pairs(dismantle) do
ins = ins[v]
end
But this unfortunately doesn’t work. It always returns the same randomly selected script at the beginning of the game no matter which script actually runs it.
So, i’ve tried using debug.getmemorycategory() instead:
local s = debug.getmemorycategory()
local fs = model:FindFirstChild(s, true)
And this identifies the scripts correctly and runs the functions from them, but unfortunately that comes to an end when clones of these scripts have been created in different locations. Instead of running them from the newly cloned scripts, it runs them from the original ones instead, even though it’s the cloned scripts that are running this module function. This is my first time experimenting with module scripts, so i don’t really understand what causes this behavior.
debug.info with the s option won’t return the call stack, but the source code of the thread provided. You might want to look into debug.traceback, which should return the callstack.
Here’s an example, when you write it in the command bar:
=debug.traceback() --an = at the start of the command bar is shorthand for print
--> print(debug.traceback()):1
where 1 is the line it was called from. But, within that string it should also contain a string of each script’s ancestry (which was involved in the call), just like Instance:GetFullName(), which you can split to find out what called it.
I tested this with a module and this is what I got:
Thank you for the help! this was very helpful, but after coming back to it the next day with a fresh mind, i’ve came up with a simpler solution that has helped me solve my problem. For those who run into the same problem as i did in the future, here’s what i did:
first, i went to my regular script and added an extra variable to it
local module = require(game.ServerScriptService:FindFirstChild("MyModule"))
script.Parent.Triggered:Connect(function() -- proximity prompt
local s = script --<<<< this is the variable i've introduced. With this variable, i am defining the script it is running from
module.myfunction(s) -- and running my function with this variable
end)
after this, i simply edited my module function
local module = {}
function module.myfunction(s)
local part = s.Parent.Parent
-- rest of the function
end
return module
And it has worked like a charm! it probably isn’t the most optimal way to do this, and the method you’ve suggested is probably better suited for things of higher complexity, but using a simple variable like this was more than good enough for my case. Thank you again for your help.
because the script may not be exactly within 2 levels deep in a part,
you may use s:GetFullName() if you only need to locate it and not work with the actual part returned.