2012-02-05 1 views
5

Моя папка содержит несколько файлов, которые составляются в таком порядке: 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, я надеюсь, что они могут быть действительными для всех файлов и функций, и я не хочу, чтобы они участвовали в сигнатуре функции.

ответ

6

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

Если игнорировать границы модуля, если связать файлы в порядке, вы даете, что у вас есть, как это:

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

Это не должно быть удивительно, что f имеет значение 0.

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

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

Edit:

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

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

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

let f() = !g1 

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

+0

Спасибо за ваш комментарий, вы объяснили, почему это происходит, но вы не объяснили, как его решить ... Я не могу изменить порядок компиляции этих файлов, что еще я могу сделать? – SoftTimur

+0

Я добавил ** Редактировать ** с некоторыми предложениями. Но трудно понять, что предложить, не зная больше о вашем коде. –

Смежные вопросы