Module Forms

This section describes what a module is and the two on-disk forms a module can take: a file module and a directory module.

A module is a Rue source file. The top-level items of the file — functions, structs, enums, and constants — are the members of the module.

A file module is a source file {name}.rue. An import of {name} that resolves to this file yields the module defined by it.

A directory module is a directory {name}/ that contains a facade file _{name}.rue directly inside it. The facade file is the directory module's root: an import of {name} that resolves to the directory module yields the module defined by the facade file. Other files inside the directory are not automatically part of the imported module; the facade reaches them via its own imports.

A file _{name}.rue is a facade only when its enclosing directory is named {name}. Anywhere else — in particular, as a sibling of a directory or a file named {name} — it is an ordinary source file with no special meaning, and it does not make {name} importable.

If both module forms exist for the same import path — a file module {path}.rue and a directory module {path}/_{basename}.rue — the import is ambiguous and rejected at compile time; neither form takes precedence. This is specified as rule 4.13:89 (error E0708).

A project mixing both forms:

main.rue            # root file
math.rue            # file module: @import("math")
utils/              # directory module: @import("utils")
├── _utils.rue      #   facade — the module root for "utils"
└── strings.rue     #   helper file, reached via the facade's imports