模块
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__"
的模块)不能成为循环引用的主题