|
|
|
@ -0,0 +1,66 @@
|
|
|
|
|
# Modules and Imports |
|
|
|
|
|
|
|
|
|
Projects naturally grow over time, and digging through 10.000 lines of code in a single file can be cumbersome. By grouping related functionality and separating code with distinct features, you’ll clarify where to find code that implements a particular feature and where to go to change how a feature works. |
|
|
|
|
|
|
|
|
|
The programs we've written so far have been in one file. As a project grows, you can organize code by splitting it into multiple modules with a clear name. |
|
|
|
|
|
|
|
|
|
In Sabre, every file is also a module. Let's take a look at a project structure and identify its modules. |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
. |
|
|
|
|
├── foo |
|
|
|
|
│ ├── bar.sb |
|
|
|
|
│ └── baz |
|
|
|
|
│ └── module.sb |
|
|
|
|
├── main.sb |
|
|
|
|
└── some_logic.sb |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
As per convention, the entrypoint for this project is the `main.sb` file in the root directory. |
|
|
|
|
|
|
|
|
|
There is a child-module called `some_logic` at the same directory-level. |
|
|
|
|
|
|
|
|
|
Below it, there is a directory called `foo`, containing the submodule `bar`. To address the `bar` module from our entrypoint, we'd import the following: |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
import "foo/bar" |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
> **Note**: File extensions in imports are optional. Importing `foo/bar.sb` would yield the same result as importing `foo/bar`. |
|
|
|
|
|
|
|
|
|
## Module entrypoints |
|
|
|
|
|
|
|
|
|
In the `foo` directory, there is another directory called `baz`, containing a single file named `module.sb`. This file is treated as a special file, since it serves as the entrypoint for that module. So, instead of importing the file explicitely: |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
// main.sb |
|
|
|
|
import "foo/baz/module" |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
we can simply import the module containing this file, and Sabre will import the contained `module.sb` instead. |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
// main.sb |
|
|
|
|
import "foo/baz" |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
## Using imported modules |
|
|
|
|
|
|
|
|
|
To use code defined in a separate module, we first need to import it. This is usually done at the top of the file, but it technically doesn't make a difference where in the document the import is defined. Once the module is imported, we can use the code inside it, as if it were in the current file. |
|
|
|
|
|
|
|
|
|
Let's say we have a module named `math.sb` in the same directory as out `main.sb`, and it defines the function `add(x: int, y: int): int`. To call it in our `main.sb`, we'd do the following: |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
import "math" |
|
|
|
|
|
|
|
|
|
fn main() { |
|
|
|
|
println(add(1, 2)) |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
If we run `main.sb`, we should see the expected output. Sabre has imported the `add` function from the `math` module. |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
$ sabre run main.sb |
|
|
|
|
3 |
|
|
|
|
``` |