How can i find which script has fired the module function?

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.

1 Like

how about just use simple warn() and its stack trace would tell you?

1 Like

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:

--LocalScript code
require("./LocalScript/ModuleScript").a()
--ModuleScript code
local module = {
	a = function()
		print(debug.traceback())
	end
}

return module

Output:

so hope it helps!

4 Likes

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.

2 Likes

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.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.