Overwrite Lua globals on module required?

Hello!

Not really sure how to phrase this question but is there a way to overwrite Lua variables on requiring a module? I’m creating a utility module for my game that returns some custom “datatypes” (basically just int rn) but was wondering if there was a way to automatically overwrite them on requiring the module instead of having to do type = module.type? My guess is that it has something to do with setfenv but I really don’t know where to go from here haha.

local module = {
	['type'] = function(obj) -- on require, 'type' would overwrite the existing type global
		local type = type(obj)
		if type == 'number' then
			if obj % 1 == 0 then
				return 'int'
			else
				return type
			end
		else
			return type
		end
	end;
}

return module

You can overwrite it but be careful. Here is a sample of code that I wrote to test it:

local t = type

function type(x)
	if x == "test" then
		return "it works"
	else
		return t(x)
	end
end

print(type("test"),type("other"))

Output: "it works string - Client - LocalScript:13"
Take note that it will put a red line underneath the function name, indicating an error. However it worked with my simple test. I do not know how effective this would be on a large scale.

I know, I just don’t know how I’d go about overwriting any predefined lua variable automatically (or if it’s even possible).

Example,

local funcs = {
    ['pairs'] = function()
        print('pairs')
    end;
    ['type'] = function()
        print('type')
    end;
    ['tostring'] = function()
        print('tostring')
    end;
}
return funcs

then on require,

require(module)
type() -- would print 'type' instead of doing the actual predefined function
pairs() -- same as above but print 'pairs'
local funcs = {
    ['pairs'] = function()
        print('pairs')
    end;
    ['type'] = function()
        print('type')
    end;
    ['tostring'] = function()
        print('tostring')
    end;
}

local env = getfenv()

for i, func in pairs(funcs) do
    env[i] = func
end

setfenv(1,env)

pairs()
type()
tostring()

Output: "pairs" "type" "tostring"

Good luck! Hope this helps.

2 Likes

Tried this:

local module = {
	['type'] = function(obj)
		local type = type(obj)
		if type == 'number' then
			if obj % 1 == 0 then
				return 'int'
			else
				return type
			end
		else
			return type
		end
	end;
	['pairs'] = function()
		print('pairs')	
	end;
}
local fenv = getfenv()
fenv['module'] = module
for i,v in pairs(module) do
	fenv[i] = v
end
return setfenv(1, fenv)

Then,

require(game.ReplicatedStorage.Modules.util) pairs()

Outputs:
require(game.ReplicatedStorage.Modules.util) pairs():1: missing argument #1 to ‘pairs’ (table expected)

Fenv doesn’t seem to be setting.

I think you will need to do setfenv outside of the module.


As seen above, setfenv returns a function or nothing. Therefore, returning the function inside the module script would basically do nothing. You are going to need to get and set the environment from the script that is requiring the module.

Edit: Correct me if I am wrong, but wouldn’t the module script have a different environment than the script requiring it, therefore wiping out the variables and such from the existing environment?

1 Like

Yeah, think you’re right.

Doing getfenv(2) returns the script requiring its environment so yeah, I would say the requirer’s environment is different than the module’s.

1 Like