Storing modular code using module repositories
Last updated at 4:40 pm UTC on 16 January 2006
(A "repository" is here used in the sense of a disk-based representation of a module in the image. In the image it is represented by the module's repository object. )
Segmenting module storage into separate or composite chunks
A whole subtree of modules can be stored together in a single chunk, called a "composite", instead of each module in its own chunk. In this case modules are stored in the repository directory at the top of the subtree. This is e.g. useful when there are a number of small submodules in your project that are no good on their own.
A module stored separate from its immediate parent has a "standalone" repository, whereas modules stored within a parent have an "implicit" repository.
By default, the repository of a module you create is implicit (the exception is when its parent doesn't allow composite storage, e.g. the #(Project) module) You use the message #beStandalone to make a module be stored in a standalone repository (separating it from its parent).
myModule repository beStandalone
An implicit repository cannot be filed out on its own, only as part of its standalone parent. So typically you will need to make your "top" module(s) standalone, and you will need to do the same for any subtrees that should be stored separately from this top module as well.
Storing on disk
ModuleInstaller upload: myModule
to store a module and all its recursive submodules to disk (separating them into different repositories as necessary).
The preference accessOnlineModuleRepositories controls whether module loading and storage should access network servers to up- and download modules, or just use what is in the local disk cache, and treat the cache as the "real" definition. Compare this to the option to "work offline" in web browsers and mail clients.
You need to have set this preference to false to avoid trying to upload your code to a server.
Checking and declaring module dependencies
Before uploading the modules, the installer will check the modules to see that they can be loaded properly. For this, each module must specify the modules it depend on so that they can be brought in as necessary when this module is eventually loaded.
The check searches for missing dependency declarations (i.e. methods or class definitions in your module refer to globals/classes in modules that this module doesn't declare). This check is equivalent to manually doing
If declarations are missing, you get the option of having it done automatically, or stopping to do it yourself. This will typically give messier declarations that if done by hand, but should do the job. This auto-declaration is equivalent to doing
This is followed by a sanity check for still missing declarations. If you here get a message that the declaration failed, then this has detected a bug somewhere, it shouldn't happen.
The second part of checking the dependencies is to check the resulting loading order. You may here get a message that some of your modules have circular dependencies, but you will get the option to proceed anyway. This is allowed since the existing code base has a staggering amount of circularities, and couldn't be filed in or out at all if this were forbidden.
However, in the case of circular dependencies, loading will depend on the Undeclared mechanism to handle "forward" references, and in short, this is not guaranteed to work properly. If there are more than one module (existing or filed in) that defines your forward reference, then Undeclared will not be able to handle this distinction and you may get bad references.
In particular, subclass-superclass relations cannot be handled by the current Undeclared mechanism.
After all the checks are done, the code will be filed out. You now ought to try loading to see if it works.