Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds a module loader subsystem that is compatible with the existing
require()
functionality but provides a much more convenient and familiar way to manage and locate modules.The net effects of the environment under
terrac
with this patch are:require()
is a closure that is created every time it is referenced. I explain why below.terralib.modpath
is now a path-delimited (;
on windows,:
on everything else) string of search paths for modulesterralib.loadmodule
is a handler that is called wheneverrequire()
is called. It is backed by a default and sane implementation but can be overridden by scripts if necessary.Modules are dot-delimited strings that represent a nested module hierarchy. For example,
std.thread.mutex
would indicate the modulemutex
that resides within the modulethread
that resides within the top-level modulestd
.Module paths that do not begin with a
.
are absolute module paths. Those that do start with a.
are relative module paths.Absolute module paths are resolved against the current
terralib.modpath
. The first path to match is considered the resolved path and thus changing the order of paths withinterralib.modpath
allows the assignation of priority.Relative module paths are resolved against the current chunk. In the event the chunk is not a file, the loader falls back to the default implementation of
require()
(or whatever is passed as the third parameter toterra.loadmodule
).Those that wish to override
terra.loadmodule
can assign a function that accepts the module name (what is passed torequire(...)
), the originating chunk filepath as an absolute path (optional), and the fallbackrequire()
to call in the event the resolution fails (optional).@aiverson pointed out a very valid caveat to a naïve implementation of this module system, which is handled correctly by this PR's implementation.
This is a slightly modified version of it.
This script correctly outputs
foofoo
, andrequire
in this case is acting not dissimilarly to Node.js's CommonJS mechanism - that is you say, you could passrequire
to another script in another directory and that script would be able to resolve modules relative to the originating file's directory.The practical impact of this is that we can start building out a standardized set of packages using this new scheme. Although it's not incredibly different than Terra's built-in
TERRA_PATH
variable, this implementation provides adequate control over path composition, giving sane semantics when combining both the environment variable and the command line options.Let me know if I've missed anything here.