Как запустить программу в OCaml на верхнем уровне с вводом из файла?
Я знаю, что для загрузки программы в OCaml нужно набрать #use "source_code_file.ml"
в toplevel, где source_code_file.ml - это файл, который мы хотим использовать.
Моя программа читает ввод из стандартного ввода. В командной строке у меня есть текстовый файл, который с перенаправлением используется в качестве стандартного ввода. Могу ли я сделать это на высшем уровне? Я хотел бы этого, потому что на верхнем уровне я могу легко видеть, какие переменные типа имеют и если вещи инициализируются с правильными значениями.
1 ответ
Если вы работаете в Unix-подобной системе, вы можете использовать Unix.dup2 для почти любого вида перенаправления ввода. Вот функция with_stdin
который принимает имя входного файла, функцию и значение. Вызывает функцию со стандартным вводом, перенаправленным из названного файла.
let with_stdin fname f x =
let oldstdin = Unix.dup Unix.stdin in
let newstdin = Unix.openfile fname [Unix.O_RDONLY] 0 in
Unix.dup2 newstdin Unix.stdin;
Unix.close newstdin;
let res = f x in
Unix.dup2 oldstdin Unix.stdin;
Unix.close oldstdin;
res
Если ваша функция не использует весь ввод, оставшийся ввод будет перепутать верхний уровень. Вот пример, который потребляет весь свой ввод:
# let rec linecount c =
try ignore (read_line ()); linecount (c + 1)
with End_of_file -> c;;
val linecount : int -> int = <fun>
# with_stdin "/etc/passwd" linecount 0;;
- : int = 86
#
Этот метод слишком прост, если вы хотите чередовать взаимодействия с верхним уровнем с вызовами вашей функции, чтобы использовать только часть ее ввода. Я подозреваю, что это сделало бы вещи слишком сложными, чтобы стоить усилий. Было бы намного проще (и, возможно, лучше) переписать ваш код для работы с явно указанным входным каналом.