ModuleScripts and "local" variables

Let’s say I have a module (simplified to get the point across):

local module = {}
module.cache = 1
function module.getCache() return module.cache end
function module.setCache(c) module.cache = c end
return module

And two scripts that require it:

Script 1
    module = require(script.Parent.ModuleScript)
    print(module.getCache())
    module.setCache(2)
    print(module.getCache())
    script.Parent.Script2.Disabled = false
Script 2
module = require(script.Parent.ModuleScript)
print("----Script 2-----")
print(module.getCache())
module.setCache(5)
print(module.getCache())

Why is the output:

1
2
----Script 2-----
2
5

And is there any way to give each script a local copy of the variables that don’t get changed/updated by other scripts interacting with the same module? The ideal output I’m looking for is:

1
2
----Script 2-----
1
5

If you wanted this, then you really don’t need to use a module at all, unless it’s for cleanliness and grouping reasons. If so, you could just give each script it’s own ModuleScript, as one of its children. That would make each module and its cache devoted to primarily its parent script.

1 Like

That’s a bit hacky but I like it! I misunderstood how modules were replicated before. I have a module that’s called upwards of 10 times a second that’s kinda processing-intensive, and adding a local cache helps speed it up.

1 Like

I believe the reason the variables are shared is that you are returning the same table address as defined as module {} as you have experimented which was created within the module script.

To solve this you can create a constructor function to initialize a different table to make the variables “local” like in object-oriented programming.

Taking the example of newCar you can do something like this to create the local copy of variables you are looking for.

local module = {}

function module.new()
    --create the new table to avoid referencing the shared table.
    local localModule = {}
--gives the local table the :functions() or .functions() methods
    setmetatable(localModule, module)

    localModule.cache = 1

    return localModule
end

function module:getCache()
      return self.cache
end

function module:setCache(c)
     self.cache = c
end

return module

However, you don’t really need the functions to set and get the cache as the constructor will return a dictionary that can be edited.

--require the above module

local newLocalModule = module.new()

print(newLocalModule.cache)
newLocalModule.cache = 5
print(newLocalModule.cache)

Yeah by convention it’s not a good idea to have one liner functions to return a singular value when you can just directly access the dictionary like above.

2 Likes

This is a cool solution! I love the somewhat rare instances in which metatables come to the rescue.

1 Like