多个文件的声明和全局引用变量

时间:2012-02-05 05:32:17

标签: variables runtime ocaml declaration

我的文件夹包含多个文件,这些文件按以下顺序编译:{{1​​}},global.mlzone.mlabs.ml

main.ml包含所有文件的一些参考变量(例如global.ml)。

let g1 = ref 0中有一个声明zone.ml

let f = !g1中,有abs.ml,它将在运行时开始时由g1 := 5运行,我认为它是main的初始化真实的运行时环境。

稍后g1将致电main。奇怪的是,我意识到需要Zone.f代替f = 0

您认为这种行为是正常的吗?如果是这样,我应该更改什么,以便将f = 5的当前值考虑在内?

PS:也许一个解决方案是在!g1中创建一个函数let f v = v,然后让zone.ml调用main。但是我在Zone.f !g1中有几个全局引用变量g1,我希望它们对所有文件和函数都有效,而且我不想让它们参与到global.ml的签名中。功能

1 个答案:

答案 0 :(得分:6)

您基本上关注模块中顶级值的评估顺序。发生这种情况的顺序与您编译文件的顺序无关,而是与链接文件时出现的顺序无关。

如果您忽略模块边界,如果按照您给出的顺序链接文件,您拥有的是这样的:

let g1 = ref 0
let f = !g1
let () = g1 := 5

f的值为0,应该不足为奇。

请注意,main不一定是运行时发生的第一件事。顶级值按链接它们时文件显示的顺序进行评估。通常,main是最后发生的最后事件(因为它的文件通常是最后一个)。

(另请注意,拥有main只是一个惯例,可能是像我这样的前C程序员所采用的。没有要求有一个名为main的函数.OCaml只是评估顶部 - 级别值按顺序。)

修改

很难说如何在不了解更多代码的情况下重构代码。问题的实质似乎是您将f定义为zone.ml中的顶级不可变值,但您希望其值遵循g1,这是一个可变值。

最简单的建议是从f中移除zone.ml的定义,并使用!g1将其替换为文件中的任何位置。

如果要在f的顶级保留名称zone.ml,则必须将其重新定义为不可变值之外的其他值。功能是最明显的选择:

let f () = !g1

然后,您将f替换zone.ml中对f ()的使用。