模块

badge

Erg允许您将文件本身视为单个记录(Record)。这称为模块

# foo.er
.i = 1
# 定义 foo 模块与定义这条记录几乎相同
foo = {.i = 1}
# bar.er
foo = import "foo"
print! foo # <module 'foo'>
assert foo.i == 1

由于模块类型也是记录类型,因此可以进行解构赋值

# 和 {sin; cos; ...} = import "math" 一样
{sin; cos} = import "math"

模块可见性

目录和文件都可以是模块 但是,在默认情况下,Erg不将目录识别为Erg模块。要让它被识别,创建一个名为__init__.er的文件 __init__.er类似于Python中的__init__.py

└─┬ bar
  └─ __init__.er

现在bar目录被识别为一个模块。如果bar中的唯一文件是__init__.er,则目录结构没有多大意义,但如果您想将多个模块捆绑到一个模块中,它会很有用。例如:

└─┬ bar
  ├─ __init__.er
  ├─ baz.er
  └─ qux.er

bar目录之外,您可以像下面这样使用

bar = import "bar"
bar.baz.p!()
bar.qux.p!()

__init__.er不仅仅是一个将目录作为模块的标记,它还控制模块的可见性

# __init__.er
# `. /` 指向当前目录。可以省略
.baz = import ". /baz"
qux = import ". /qux"
.f x =
    .baz.f ...
.g x =
    qux.f ...

当你从外部导入 bar 模块时,baz 模块可以访问,但 qux 模块不能。

循环依赖

Erg 允许您定义模块之间的循环依赖关系。

# foo.er
bar = import "bar"
print! bar.g 1
.f x = x
# bar.er
foo = import "foo"
print! foo.f 1
.g x = x

但是,由过程调用创建的变量不能在循环引用模块中定义 这是因为 Erg 根据依赖关系重新排列定义的顺序

# foo.er
bar = import "bar"
print! bar.x
.x = g!(1) # 模块错误:由过程调用创建的变量不能在循环引用模块中定义
# bar.er
foo = import "foo"
print! foo.x
.x = 0

此外,作为入口点的 Erg 模块(即 __name__ == "__main__" 的模块)不能成为循环引用的主题