Глава 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
.