And I was all happy with it and the "require.main == module.id"
proposal but then I had a thought: you will probably also want to get
hold of the path of the main module which is only available in
"module.main" when you are in the main module, but otherwise not
available.
So how about this one change:
Instead of "require.main" being the id of the main module, make it the
main module's "module" object. This lets you do the following.
if (require.main === module) { /* I am the main */ }
require(require.main.id);
as you could before, but you can now also do
loadResourceFrom(new Path(require.main.path).parent());
// That is if the FS spec had a 'parent' method, which seems to be
lacking.
Show of hands for making this change?
* Ash Berlin (obviously)
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]
This is strictly more useful. It'll be a mild pain to migrate, but so be it.
+1
Kris Kowal
Wiki updated. Does anyone have any problem with the proposal as it now
stands on the wiki. Staying silent counts as no problem.
Looking back over the thread linked there, the other issue was
"module.path" vs ".fileName" vs ".uri". It is my understanding that at
some future point we will add a "module.resource()" function, so
storing the path/directory of the module shouldn't be needed, so I
therefore think we should have "module.uri". If we can reach an
agreement on this last point, this proposal can offically be ratified.
Which would be nice.
-ash
I have the feature in my "refactor" branch with a shim that Ash Berlin
contrived to make it backward compatible with the module.id idiom
(providing a .toString() on the module object). The shim works if
you've used the idiom:
if (require.main == module.id) {
}
but not if you used the idiom:
if (require.main === module.id) {
}
And provides support for migration to:
if (require.main == module) {
}
The implementation was a little weird, but not insurmountable.
So, the pros are:
* You can use require.main.path and other metadata of the main module
from within any module.
The cons (and counter arguments where applicable) are:
* You can use other metadata on the main module, that might
conceivably be private to that module.
** Modules within a sandbox are not presently security membranes
*** But they should be treated as such anyway as often as possible for safety.
* The idiom of a "main" only works if there's only one "main". This
could be a problem if there's a different "main" in each thread.
** We can specify that there may be no "main" if it would be ambiguous.
** This isn't really a problem; the idiom of a "main" module works as
long as there's one "main" for each "sandbox" (system of modules, a
module memo and some other state like which module was the main
module) and one "sandbox" per "thread", "worker", "vat", "process" or
whatever you call your shared-nothing async-message-passing system.
* Coupling: the process of requiring the "main" module must be
special and the usual module loader machinations must accommodate it,
which introduces coupling.
** It's not too bad; the coupling remains in the sandboxing system's
logic at least for Narwhal, so no new interfaces are needed. [1] [2]
I'm indifferent on the issue. It would not be hard to avoid merging
these changes.
Kris Kowal
[1] http://github.com/kriskowal/narwhal/blob/refactor/lib/sandbox.js#L61-66
[2] http://github.com/kriskowal/narwhal/blob/refactor/lib/sandbox.js#L166-170
Wiki updated. Does anyone have any problem with the proposal as it nowstands on the wiki. Staying silent counts as no problem.
I know I'm a bit late,
First, there's implementational complexity. The requirement of
referential identity means the setup of require.main and instantiation
of the main module have to be tightly coupled.
Second, it implies that there will only be one instance of the main
module, which may be the case for simple, single-threaded scripts. But
if a main module just starts a server or otherwise launches some
threads/workers and then exits, other threads requiring the main
module will create new instances (at least in Helma NG, modules are
singletons only within one thread/context, and I really think that's
the way it should be).
Finally, I think there's a conceptual problem. The way I see it, the
module meta-object is meant to be private to the module it belongs to.
Exposing it as require.main would call for the object to be sealed
IMO.
But that clashes with the requirement for referential identity
with the actual module meta-object, which is needed for the
require.main == module check to work.
So all points considered I would prefer for require.main to remain the
string id of the main module. Has anybody made major investments in
this feature already? As far as I can tell, neither Narwhal nor
Flusspferd are implementing it yet.
Hannes