Объявления и глобальные ссылочные переменные для нескольких файлов - PullRequest
5 голосов
/ 05 февраля 2012

Моя папка содержит несколько файлов, которые скомпилированы в следующем порядке: global.ml, zone.ml, abs.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.

Как вы думаете, это поведение нормально? Если так, что я должен изменить, чтобы он учитывал текущее значение !g1?

PS: Возможно, одно из решений - сделать функцию let f v = v в zone.ml, а затем позволить main вызвать Zone.f !g1. Но у меня есть несколько глобальных ссылочных переменных, таких как g1 в global.ml, я надеюсь, что они могут быть действительными для всех файлов и функций, и я не хочу вовлекать их в сигнатуру функции.

1 Ответ

6 голосов
/ 05 февраля 2012

В основном вас интересует порядок оценки значений верхнего уровня в ваших модулях.Порядок, в котором это происходит, не связан с порядком, в котором вы компилируете файлы, а скорее с порядком, в котором они появляются, когда вы связываете файлы.Если вы игнорируете границы модуля, если вы связываете файлы в указанном вами порядке, то получается следующее:

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

Не удивительно, что f имеет значение 0.

Обратите внимание, что ваш main не обязательно первое, что происходит во время выполнения.Значения верхнего уровня оцениваются в том порядке, в каком файлы появляются при их связывании.Очень часто main - это последний объект верхнего уровня (поскольку его файл обычно является последним).

(Также обратите внимание, что наличие main вообщепросто соглашение, предположительно принятое бывшими программистами Си, такими как я. Нет необходимости иметь функцию с именем main. OCaml просто оценивает значения верхнего уровня по порядку.)

Edit:

Трудно сказать, как реструктурировать ваш код, не зная об этом больше.Суть вашей проблемы в том, что вы определяете f как неизменное значение верхнего уровня в zone.ml, но вы хотите, чтобы его значение следовало за g1, что является изменяемым значением.

Самое простоеБыло бы предложено убрать определение f из zone.ml и заменить его везде в файле на !g1.

Если вы хотите сохранить имя f на верхнем уровне в zone.ml, вы должны переопределить его как нечто иное, чем неизменное значение.Функция является наиболее очевидным выбором:

let f () = !g1

Тогда вы бы заменили использование f в zone.ml на f () вместо.

...