Глава 9 . Интерактивная система (ocaml)
В этой главе описывается интерактивная система Objective
Caml, преднзначенная для использования языка в циле
чтения-компиляции-вызова. В этом режиме система считывает фразы
Caml из ввода, проверяет тип, компилирует и выполняет и, а затем
выводит распознанный тип и значение результата, если он
есть. Перед чтением каждой фразы система выводит символ
# (диез).
Ввод может занимать
несколько строк. Он заканчивается ;; (двумя
точками с запятыми) и состоит из одной или нескольких фраз со
следующим синтаксисом:
| toplevel-input | ::= | { toplevel-phrase } ;; |
| toplevel-phrase | ::= |
definition
| expr | # ident directive-argument |
| definition | ::= |
let
[
rec
]
let-binding
{
and
let-binding
}
| type-definition | exception-definition | module module-name ( : module-type ) = module-expr | module type modtype-name = module-type | open module-path | external value-name : typexpr=external-decalaration | type-definition | exception-definition |
| directive-argument | ::= |
nothing | string-literal | integer-literal | value-path |
Фраза состоит из определений, подобных тем, что включаются в
реализации единиц компиляции, или в выражениях модулей
struct ... end. Определение связывает имена
значений, имена типов, исключения, имена модулей и имена типов
модулей. Интерактивная система осуществляет само связывание и
выводит определенные типы и значения, если они есть.
Кроме того, фраза может содержать директиву
open (см. раздел 6.11) или выражение
(см. раздел 6.7). Выражение вычисляется без связывания, и
система выводит его результат.
Наконец, фраза может включать директивы интерактивной системы,
начинающиеся со знака #. Они управляют
работой интерактивной системы и описаны ниже, в разделе 9.2.
- UNIX
-
Интерактивная система запускается командой
ocaml:ocaml options objects # интерактивный режим ocaml options objects scriptfile # пакетный режим
Опции описаны ниже. Параметр
objectsвключает имена файлов с расширениями.cmoили.cma- интерпретатор загружает их сразу после установки опций. Параметрscriptfile- это любое имя файла без расширения.cmoили.cma.Если параметр
scriptfileотсутствует в командной строке, система запускается в интерактивном режиме - фразы читаются из стандартного ввода, результаты выводятся в стандартный вывод, ошибки - в стандратный поток ошибок. Знак конца файла в стандартном вводе останавливаетocaml(см. также директиву#quitв разделе 9.2).При запуске, но до чтения первой фразы, из текущего каталога считывается файл
.ocamlinit(если он есть). Его содержимое читается как последовательность фраз OCaml и выполняеся как в при использовании директивы#use. При вычислении эти фразы не выводятся.Интерактивная система не редактирует строки, однако ее легко можно использовать в комбинации с внешним редактором строк типа
fepкомандойfep -emacs ocamlилиfep -vim ocaml. Кроме того,ocamlможет запускаться в GNU Emacs, что позволяет использовать все возможности этого редактора (см. подкаталогemacsв дистрибутиве Objective Caml).Анализ, компиляция и выполнение текущей фразы в любой момент могут быть прерваны клавишами
ctrl-c(или, если точнее отправкой сигналаsigintrпроцессуocaml). Интерактивная система в этом случае немедленно возвращается к приглашению#.Если в командной строке задан параметр
scriptfile, интерактивная система переходит в режим сценария: содержимое файла считывается как последовательность фраз Objective Caml и выполняется как при использовании директивы#use(раздел 9.2). Результаты компиляции не выводятся. По окончании файла работа командыcamlзавершается. Команды из стандартного ввода не читаются.Sys.argvмодифицируется, причем все параметры Objective Caml игнорируются, а вSys.argv.(0)помещается имя файла сценария.Если первая строка файла сценария начинается с символов
#!, она пропускается. Таким образом, теоретически возможно делать файлы сценариев исполняемыми и помещать в первую строку что-то вроде#! /usr/local/bin/ocaml. Однако в большинстве инсталляций командаocamlсама является сценарием командной оболочки, а операционные системы Unix как правило не умеют работать с вложенными сценариями. - Windows
-
Кроме команды текстового режима
ocaml, которая работает точно так же, как и под Unix, существует графический интерфейс интерактивной системы. Он называетсяocamlwin.exeи может запускаться как из файлового менеджера, так и из оболочки Windows.Окно "Terminal" разделено на две области. В нижней вводятся и редактируются фразы, верхняя содержит копию ввода и вывод интерпретатора. Клавиша "Return" пересылает ввод интерпретатору, клавиша "Enter" просто добавляет символ новой строки (назначение клавиш конфигурируется в меню "Preferences").
Содержимое окна ввода может быть изменено в любой момент через стандартный интерфейс Windows. В отдельном окне показаны ранее введенные фразы.
Для выхода из приложения
Ocamlwinиспользуется либо пункт менюFile|Exit, либо функцияquit, описанная ниже.Анализ, компиляция и выполнение текущей фразы в любой момент могут быть прерваны командой меню
Interrupt Objective Caml. Интерактивная система в этом случае немедленно возвращается к приглашению#.
9 . 1 Опции
ocaml распознает следующие опции командной
строки:
- -I directory
-
Добавяет указанную директорию к списку директорий, в которых ищутся исходные тексты и компилированные файлы. По умолчанию сначала используется текущий каталог, затем стандартная библиотека. Директории, заданные этой опцией помещаются в список поиска после текущего каталога, в том порядке, как они указаны, но до стандартной библиотеки.
Если перед
directoryстоит знак+, путь берется относительно стандартной библоитеки. Например,-I +labltkдобавит к пути поиска подкаталогlabltkкаталога стандартной библиотеки.Кроме того, каталоги можно добавить к пути поиска непосредственно после запуска интрепретатора директивой
#directory. - -nolabels
-
Игнорировать обязательные метки в типах. В этом случае метки не могут использоваться в приложениях, и порядок аргументов становится строгим.
- -principal
-
Во время проверки типов компилятор проверяет также информацию о путях, следя чтобы все типы выводились приниципально, Программы, допустимые в режиме
-principal, допустимы и в режиме по умолчанию с эквивалентными типами. - -rectypes
-
Разрешает во время проверки типа произвольные рекурсивные типы. По умолчанию поддерживаются только рекурсивные типы с рекурсией по типу объекта.
- -unsafe
-
См. описание соответствующей опции
ocamlcв гл. 8. Отключает проверку границ на массивах и обращении к строкам (конструкцииv.(i)иs.[i]). Программы, собранные с этой опцией несколько быстрее, но не являются безопасными: при обращении к элементу за пределами массива или границы строки может произойти все, что угодно. - -w warning-list
-
Включает или выключает предупреждение в соответствие со значением аргумента
warning-list.
- Unix
-
Проверяются также следующие переменные среды:
- LC_CTYPE
-
Если эта переменная установлена в значение
iso8859-1, знаки с акцентам из набора Latin-1 в строках и символьных литералах выводятся как есть. В противном случае они печатаются десятичными контрольными последовательностями (вида \ddd). - TERM
-
При выводе сообщений об ошибках интерпретатор пытается визуально подчеркивать место обнаружения ошибки. Он проверяет переменную окружения
TERM, чтобы определить тип терминала и выяснить его возможности в базе данных терминалов.
9 . 2 Директивы
Ниже перечислены директивы, которые позволяют контролировать работу интерпретатора, загружать в память файлы и отслеживать ход выполнения программы.
Обратите внимание: все директивы начинаются со знака
# (диез). Он должен печататься перед
директивой, но его не следует путать с приглашением
интрепретатора. Если, например, напечатать
#quit;;, работа интерпретатора завершится,
ввод же quit;; приведет лишь к ошибке
"unbound value quit".
- #quit;;
-
Завершает работу интерпретатора
ocaml. - #labels bool;;
-
Игнорирует метки в типах функций, если аргумент установлен в false, либо переключает в режим по умолчанию (коммутирующий), если аргемент установлен в true.
- warnings "warnings-list";;
-
Включает или выключает предупреждения согласно значению аргумента.
- #directory "dir-name";;
-
Добавляет указанный каталог к списку директорий, в которых ищутся исходные тексты и компилированные файлы.
- #cd "dir-name";;
-
Изменяет текущий каталог.
- #load "file-name";;
-
Загружает в память байткод из объектного файла (
.cmo), созданного компиляторомocamlc. - #use "file-name";;
-
Читает, компилирует и выполняет фразы из указанного файла с исходным кодом. Включение буквальное: фразы обрабатываются так, будто они вводятся со стандатного ввода. Чтени файла останавливается при первой же ошибке.
- #install-printer printer-name;;
-
Эта директива регистрирует функцию printer-name в качестве принтера для значений, типы которых совпадают с типом аргумента функции. Иными словами, интерактивная система будет вызывать printer-name, как только ей потребуется вывести подобное значение.
Функция должна иметь тип Format.formatter ->t-> unit, где t - тип значения, и выводить строковое представление значения типа t на заданном форматировщике с помощью функций библиотеки
Format. Из соображений обратной совместимости функция должна также иметь тип t-> unit и предоставлять вывод для стандартного форматировщика, но такое использование считается устаревшим. - #remove-printer printer-name;;
-
Удаляет указанную функцию из таблицы принтеров.
- #trace function-name;;
-
После выполнения этой директивы все вызовы функции function-name будут "трассироваться" - аргументы и результаты, а также исключения, возбужденные либо самой функией, либо вызываемой ей функцией, печатаются при каждом ее вызове. Если функция является производной, каждый аргумент печатается так, будто он передается функции.
- #untrace function-name;;
-
Останавливает трассировку указанной функции.
- #untrace_all;;
-
Останавливает трассировку всех функций.
- #print_depth n;;
-
Ограничивает вывод значений максимальной глубиной n. Части значений с глубиной, превосходящей n выводятся как
...(многоточие). - #print_length n;;
-
Ограничивает количество узлов выводимых значений максимальным числом n. Оставшиеся части выводятся как
...(многоточие).
9 . 3 Интерпретатор и система модулей
Фразы в интерактивной системе могут ссылаться на
идентификаторы, определенные в единицах компиляции точно так
же, как и в отдельных единицах компиляции - либо по полным
именам (Modulename.localname), либо с
помощью конструкции open и неполного имени
(см. раздел 6.3).
Однако реализация единицы, на имена котрой предполагается
ссылаться уже должна быть загружена в память. При запуске
интерактивная система включает все реализации модулей
стандартной библиотеки, а реализации пользовательскиз модулей
загружаются директивой #load, описанной
выше. Ссылка на единицу, реализации которой не найдено,
приведет к ошибке "Reference to undefined global
`...'".
Обратите внимание, что фраза open
mod всего лишь обеспечивает доступ к
компилированному интерфейсу (.cmi) модуля
mod, не загружая его реализации и не сообщая об
ошибке, если она не будет найдена. Ошибка "reference to
undefined global mod" возникает только в том
случает, если выполняется значение или определение модуля,
ссылающегося на mod.
9 . 4 Распространенные ошибки
В этом разделе описываются наиболее распространенные сообщения об ошибках.
- Cannot find file filename
-
Указанный файл не обнаружен в текущем каталоге или каталогах, входящих в пусть поиска.
Если
filenameпредставлен в форматеmod.cmi, то это означает, что обнаружена ссылка на модульmod, который еще не скомпилирован. Чтобы исправить эту ошибку, достаточно скомпилировать предварительно файлmod.mliилиmod.ml.Если
filenameпредставлен в форматеmod.cmo, то это означает, что обнаружена попытка загрузить директивой#loadнесуществующий файл с байткодом. Чтобы исправить ошибку, надо скомпилировать файлmod.ml.Если программа включает несколько каталогов, они могут не попасть в пусть поиска. В таком случае их надо добавить директивой
#directory. - This expression has type t1, but is used with type t2
-
См. раздел 8.4.
- Reference to undefined global mod
-
Реализаци модуля не загружена директивой
#load. См. раздел 9.3.
9 . 5 Заказные интерпретаторы
Команда ocamlmktop создает
интерпретаторы Objective Caml, котрые загружат при запуске
пользовательский код.
Она принимает в качестве аргумента набор файлов
.cmo и .cma и компонует
их с объектными файлами, реализующими интреактивную систему
Objective Caml. Типичный пример:
ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
Здесь создается файл с байткодом mytoplevel, включающий интерактивную систему Objective Caml и код из трех файлов .cmo. Этот файл уже является исполняемым и запускается так:
./mytoplevel
В результате загружается обычный интерпретор, однако код из foo.cmo, bar.cmo и gee.cmo уже находится в памяти, словно были введены директивы
#load "foo.cmo";; #load "bar.cmo";; #load "gee.cmo";;
Впрочем, модули Foo, Bar и Gee не открыты, поэтому надо ввести
open Foo;;
если это потребуется.
9 . 6 Опции ocamlmktop
Команда ocamlmktop допускает следующие опции командной строки:
- -cclib libname
-
Передает компоновщику С опцию
-llibnameпри компоновке в "заказном" режиме. См. описание соответствующей опцииocamlcв гл. 8. - -ccopt option
-
Передает указанные опции компилятору и компоновщику С при компоновке в "заказном" режиме. См. описание соответствующей опции
ocamlcв гл. 8. - -custom
-
Компоновка в "заказном" режиме. См. описание соответствующей опции
ocamlcв гл. 8. - -I directory
-
Добавяет указанную директорию к списку директорий, в которых ищутся компилированные файлы (
.cmoи.cma). - -o exec-file
-
Задает имя файла интерпретатора, создаваемого компоновщиком. По умолчанию это
a.out.


