<DEBUNKED> Passing arguments to ModuleScript using require(Module, ...)

This got debunked by @Anaminus . It's not possible, so ignore.

So, this is simply a thought … but I’m curious on what others think.

Currently, I am creating a game in which I’m dividing pieces of the code into ModuleScripts. However, I still need the ModuleScripts to contain the Environment of it’s caller. My solution is to return a function in which the requiring Script will use setfenv to “merge” the Environment. Here’s a sloppy example below:

ServerScript requiring our Module

local RequiredModule = require(script:WaitForChild("AModuleAaay"), {
   "This table contains something I want to pass",
   "Oh look, another thing I wanna pass",
   true
}, true, false, ...)

ModuleScript being required by ServerScript

local PassedArguments = {...} -- command line anyone? :))

-- do stuff with PassedArguments!!!.... aay

My reasoning for such implementation is simple:
Previously, I requested the implementation of a SharedModule, and learned of the many reasons why such Module shouldn’t exist. Being a wee more seasoned, I now understand the reasoning for not doing such hacks … Modules are supposed to be plug and play, right? So, instead of attempting to unify a ModuleScript into the requiring Script’s environment, I propose we add the ability to pass arguments to the ModuleScript using require. As a developer, I believe this would significantly help developers in making code modular, as we would be able to pass variables we need through the function without having to do ugly return function hacks. So yea … thats my idea.

Disclaimer: this was written at 6:10AM (and I sleep in the day, and haven’t gone to bed yet …) and I am exausted. I probably did a horrible job pitching this idea, and expect to see replies to such horrible pitch. If you have questions, I’ll do my best to answer them after a good days nights sleep!

It seems a little inappropriate to use require to pass in those types of things. These arguments are for use in your module’s implementation and not the require function, so why are we using require to hold these values instead of using the module itself? I’m not even seeing the issue with using a returned function to pass in the environment. Why is this an issue?

--[[ Module ]]--
local requirerEnv

local module = {}

function module:Init(env)
    requirerEnv = env
    blowThatPopsicleStand()
end

return module

--[[ Script ]]--
require(module):Init(getfenv())

That’s technically one way, but I just want to post this here from my previous “SharedModule” proposal:

QUICKLY NOTING THAT THIS DID NOT QUOTE CORRECTLY, BUT SHOULD GET THE MESSAGE THROUGH

He even mentions using the similar idea you responded with. However, I feel this would be a better suited alternative as passing arguments with require would provide a clean way of sharing data without relying on _G/shared, and gives you more control in how you desire to return your ModuleScript, allowing you to make a ModuleScript more “private” if you will. I dunno, maybe I’m just overthinking here, but if I had a choice to pass arguments using require or to use the example you posted above, I would use require to pass arguments in a heartbeat.

EDIT:
realized @ pings a user whoops. sorry for unnecessary notification.

To clarify, do you want to pass the calling script’s environment in or just regular arguments? Either way you can still use what I mentioned – it doesn’t have to pass the environment specifically.

--[[ Module ]]--
local args

local module = {}
function module:Init(...)
    args = {...}
end
return module

--[[ Script ]]--
require(module):Init("a","b","c")
1 Like

Just arguments. And yes … I understand I can pass arguments using such method. However, as I stated previous …

The point is to keep ModuleScripts “modular”, while allowing them to still pass data around. Thus, this previously.

How does the bit you quoted relate to this? Passing arguments like that doesn’t involve _G/shared, and what’s “[returning] your ModuleScript”? Returning the instance? return script. Returning a manipulable object? local module = {} --[[insert methods here]] return module. You can even do both: local module = {}; module.Instance = script; --[[insert methods here]] return module.

I don’t understand how it doesn’t relate. The purpose of this thread is to pitch the idea of enabling require() to pass arguments to the required ModuleScript. You’ve stated one solution, which is to return a “table” and have it initialize from there. If you’re doing OOP, I can understand where you would come from this. However, some developers don’t exactly do OOP, or use a mix of it. I do a mix, and when I require a Module, I want it to be ready to use right away (Unless I’m doing OOP with said Module, then having an “initializer” function is fine). The current implementation doesn’t allow for such, and limits my ability to create code in the style I’m used to do.

As I was writing this, I thought this would actually be a benefit to OOP users, as they could “initialize” classes by passing the required arguments through require instead of having to do Module.new(). Call me nit picky, but I think it would help clean up code a lot.

I’m really not seeing why this is all that great. You get a small syntax change and can do: require(module, "arg1", "arg2") instead of require(module)("arg1", "arg2") and that’s it. By itself that hardly even makes a difference, and by changing require you’re needlessly differentiating it from Lua’s default require and now require is taking arguments it doesn’t even use.

I don’t think the huge flaw has been mentioned yet: modules only run once, multiple scripts can require a module, and the order in which scripts require the module is undefined. Passing arguments to the module through require is not compatible with this.

2 Likes

True. I totally forgot about this. With that in mind, it’s rather pointless to continue this as it just wouldn’t work.

@Lilly_S Lock please?