Modules and libraries
Put functions and types you reuse in a module, import them into other scripts with a version, and know the rules about cycles, names and limits.
When the same function turns up in three scripts, move it to a module. A module is a script whose job is to be imported: it draws nothing of its own, it only exports names. Other scripts import it and call what it exports.
Write a module#
A module starts with module Name instead of indicator "Name". Anything marked export can be imported; the rest is private.
// A module: a running mean kept in a record. Other scripts import it by name and version.
module Stats
edition = 1
export type Stats
n: int = 0
total: float = 0
export fn Stats.add(self: Stats, x: float)
self.n += 1
self.total += x
export fn Stats.mean(self: Stats): float = if self.n > 0 then self.total / self.n else naA module draws nothing by itself, so it cannot run on a chart on its own: the engine refuses it with This is a library: other scripts import it; it does not draw on its own.
Import it#
import Owner/Name@version as alias brings a module in. Only your own modules can be imported in this release: the owner is written Me (the engine finds the module by its name and does not look at the owner), the name is the module's name, and the version is written 1. The alias is how you reach what the module exports.
// Using the module: the running mean of every close so far, drawn next to the close.
indicator "Running mean"
edition = 1
display = price
import Me/Stats@1 as mu
state stats = mu.Stats(n = 0)
stats.add(close)
plot(stats.mean(), name = "Mean of every close so far", color = color.orange)
plot(close, name = "Close", color = color.gray)mu.Stats(n = 0)builds a record of the imported type, by naming its fields.stats.add(close)andstats.mean()call methods that the module exports.- The module runs with a separate memory for every import: two scripts that import it do not share state.
An import without a version is refused:
indicator "An import with no version"
edition = 1
import Me/Stats as mu
plot(close)Rules#
- Versions. The version is required in the text of the import. This release has no second version of a module: write
@1. - Names. If you use a name that the module does not export, the error is
E3172. Onlyexported functions, types and enums are visible. - No cycles. A module may not import itself, directly or through other modules. The error is
E-IMPORT-CYCLE, and the message names the chain,a -> b -> a. - A module that is not there. Importing one you do not have gives an error that names the library.
Limits#
Modules are bounded before they compile:
| Limit | Value |
|---|---|
| Modules importing modules, deep | 8 |
| Imports compiled for one script, including those inside modules | 64 |
| Characters of module text compiled for one script | 1,000,000 |
Real scripts use one level and a few imports. Beyond a limit the script stops with E-IMPORT-DEPTH, E-IMPORT-COUNT or E-IMPORT-SIZE, naming the one that was passed.
See also: Functions, types and enums, Limits and budgets.