Глава 14 Система верхнего уровня или REPL (ocaml)
В этой главе описывается ocaml — система верхнего уровня для OCaml, которая позволяет интерактивно работать с системой OCaml в цикле чтения-вычисления-печати (REPL). В этом режиме система многократно считывает фразы OCaml из входного потока, затем проверяет их типы, компилирует и вычисляет, после чего выводит выведенный тип и результирующее значение, если оно есть. Конец файла на стандартном вводе завершает работу ocaml.
Ввод для системы верхнего уровня может занимать несколько строк. Он начинается после приглашения # (решётки), выводимого системой, и завершается последовательностью ;; (двойная точка с запятой), за которой могут следовать пробельные символы и комментарии, а затем конец строки. Ввод для системы верхнего уровня состоит из одной или нескольких фраз верхнего уровня со следующим синтаксисом:
|
Фраза может состоять из последовательности определений, подобных тем, которые встречаются в реализациях единиц компиляции или в выражениях модулей struct … end. Определения могут связывать имена значений, имена типов, исключения, имена модулей или имена типов модулей. Система верхнего уровня выполняет связывания, а затем выводит типы и значения (если они есть) для определённых таким образом имён.
Фраза также может состоять из выражения-значения (раздел 11.7). Оно просто вычисляется без выполнения каких-либо связываний, а его значение выводится.
Наконец, фраза может состоять из директивы верхнего уровня, начинающейся с # (знака решётки). Эти директивы управляют поведением системы верхнего уровня; они перечислены ниже в разделе 14.2.
Unix: Система верхнего уровня запускается командой ocaml следующим образом:ocaml options objects # interactive mode ocaml options objects scriptfile # script modeoptions описаны ниже. objects — это имена файлов, заканчивающиеся на .cmo или .cma; они загружаются в интерпретатор сразу после задания options. scriptfile — это любое имя файла, не заканчивающееся на .cmo или .cma.Если в командной строке не задан scriptfile, система верхнего уровня переходит в интерактивный режим: фразы считываются со стандартного ввода, результаты выводятся в стандартный вывод, ошибки — в стандартный поток ошибок. Конец файла на стандартном вводе завершает работу ocaml (см. также директиву #quit в разделе 14.2).
При запуске (до чтения первой фразы) содержимое файла инициализации считывается как последовательность фраз OCaml и выполняется так же, как директива #use, описанная в разделе 14.2. Результат вычисления каждой фразы не отображается.
Файлом инициализации становится первый найденный файл из следующего списка:
- .ocamlinit в текущем каталоге;
- XDG_CONFIG_HOME/ocaml/init.ml, если XDG_CONFIG_HOME — абсолютный путь;
- иначе, в Unix, HOME/ocaml/init.ml или, в Windows, ocaml\init.ml в каталоге LocalAppData (например, C:\Users\Bactrian\AppData\Local\ocaml\init.ml);
- ocaml/init.ml в любом из абсолютных путей, указанных в XDG_CONFIG_DIRS. Пути в XDG_CONFIG_DIRS разделяются двоеточиями в Unix и точками с запятой в Windows;
- если в XDG_CONFIG_DIRS нет абсолютных путей, то /usr/xdg/ocaml/init.ml в Unix или ocaml\init.ml в одном из каталогов LocalAppData (например, C:\Users\Bactrian\AppData\Local), RoamingAppData (например, C:\Users\Bactrian\AppData\Roaming) или ProgramData (например, C:\ProgramData) в Windows;
- HOME/.ocamlinit, если значение HOME не пусто;
Система верхнего уровня не выполняет редактирование строк, но её можно без труда использовать вместе с внешним редактором строк, например ledit или rlwrap. Также доступна усовершенствованная система верхнего уровня utop. Ещё один вариант — использовать ocaml в Gnu Emacs, который предоставляет все возможности редактирования Emacs (команда run-caml из библиотеки inf-caml).
В любой момент разбор, компиляцию или вычисление текущей фразы можно прервать нажатием ctrl-C (или, точнее, отправив сигнал INTR процессу ocaml). После этого система верхнего уровня немедленно возвращается к приглашению #.
Если в командной строке для ocaml указан scriptfile, система верхнего уровня переходит в режим выполнения скрипта: содержимое файла считывается как последовательность фраз OCaml и выполняется так же, как при использовании директивы #use (раздел 14.2). Результат вычисления не выводится. По достижении конца файла команда ocaml немедленно завершает работу. Команды со стандартного ввода не считываются. Sys.argv преобразуется: все параметры OCaml игнорируются, а имя файла скрипта помещается в Sys.argv.(0).
В режиме выполнения скрипта первая строка игнорируется, если начинается с #!. Таким образом, сам скрипт можно сделать исполняемым и поместить в первую строку #!/usr/local/bin/ocaml, чтобы система верхнего уровня запускалась автоматически при выполнении скрипта. Однако в большинстве установок OCaml сама программа ocaml является скриптом #!, а ядра Unix обычно не обрабатывают вложенные скрипты #!. Лучше поместить в первую строку скрипта следующее:
#!/usr/local/bin/ocamlrun /usr/local/bin/ocaml
1 Параметры
Команда ocaml распознаёт следующие параметры командной строки.
- -absname
- Принудительно указывать в сообщениях об ошибках абсолютные пути к файлам.
- -no-absname
- Не пытаться указывать в сообщениях об ошибках абсолютные имена файлов.
- -args filename
- Считать из filename дополнительные аргументы командной строки, разделённые символами новой строки. Передать скрипт scriptfile системе верхнего уровня через файл невозможно.
- -args0 filename
- Считать из filename дополнительные аргументы командной строки, разделённые нулевыми символами. Передать скрипт scriptfile системе верхнего уровня через файл невозможно.
- -i-variance
- Выводить вычисленную вариантность параметров типов для каждого объявления типа. Без этого параметра вариантность выводится только для приватных типов или типов без манифеста (например, абстрактных типов).
- -I directory
- Добавить указанный каталог в список каталогов, в которых выполняется поиск исходных и скомпилированных файлов. По умолчанию сначала выполняется поиск в текущем каталоге, затем — в каталоге стандартной библиотеки. Каталоги, добавленные с помощью -I, просматриваются после текущего каталога в порядке их указания в командной строке, но до каталога стандартной библиотеки. См. также параметр -nostdlib.
Если указанный каталог начинается с +, он трактуется как относительный к каталогу стандартной библиотеки. Например, -I +unix добавляет подкаталог unix стандартной библиотеки в путь поиска.
Каталоги также можно добавлять в список после запуска системы верхнего уровня с помощью директивы #directory (раздел 14.2).
- -init file
- Загрузить указанный файл вместо файла инициализации по умолчанию. Файлом инициализации по умолчанию становится первый найденный файл из следующего списка:
- .ocamlinit в текущем каталоге;
- XDG_CONFIG_HOME/ocaml/init.ml, если XDG_CONFIG_HOME — абсолютный путь;
- иначе, в Unix, HOME/ocaml/init.ml или, в Windows, ocaml\init.ml в каталоге LocalAppData (например, C:\Users\Bactrian\AppData\Local\ocaml\init.ml);
- ocaml/init.ml в любом из абсолютных путей, указанных в XDG_CONFIG_DIRS. Пути в XDG_CONFIG_DIRS разделяются двоеточиями в Unix и точками с запятой в Windows;
- если в XDG_CONFIG_DIRS нет абсолютных путей, то /usr/xdg/ocaml/init.ml в Unix или ocaml\init.ml в одном из каталогов LocalAppData (например, C:\Users\Bactrian\AppData\Local), RoamingAppData (например, C:\Users\Bactrian\AppData\Roaming) или ProgramData (например, C:\ProgramData) в Windows;
- HOME/.ocamlinit, если значение HOME не пусто;
- -keywords version+list
- Задать ключевые слова в соответствии со спецификацией version+list.
Спецификация начинается с необязательного номера версии, задающего базовый набор ключевых слов, за которым следует разделённый символами + список дополнительных ключевых слов, добавляемых к базовому набору.
Если номер версии явно не указан, базовым набором ключевых слов считается набор из текущей версии OCaml. Если в исходном коде присутствуют дополнительные ключевые слова, неизвестные текущей версии языка, возникает ошибка.
- -labels
- Метки учитываются в типах, их можно использовать при вызовах, а именованные параметры можно указывать в любом порядке. Это значение используется по умолчанию.
- -no-app-funct
- Отключить аппликативное поведение функторов. При использовании этого параметра каждое применение функтора создаёт новые типы в результате, и два применения одного функтора к одному и тому же аргументу дают две несовместимые структуры.
- -noassert
- Не компилировать проверки утверждений. Обратите внимание, что специальная форма assert false всегда компилируется, поскольку для неё предусмотрена специальная обработка типов.
- -nolabels
- Игнорировать необязательные метки в типах. Метки нельзя использовать при вызовах, а порядок параметров становится строгим.
- -noprompt
- Не отображать приглашение при ожидании ввода.
- -nopromptcont
- Не отображать дополнительное приглашение при ожидании продолжения многострочного ввода. Этот параметр следует использовать, например, при запуске ocaml в окне emacs.
- -nostdlib
- Не включать каталог стандартной библиотеки в список каталогов, в которых выполняется поиск исходных и скомпилированных файлов.
- -ppx command
- После разбора передать абстрактное синтаксическое дерево препроцессору command. Модуль Ast_mapper, описанный в главе 31: Ast_mapper , реализует внешний интерфейс препроцессора.
- -principal
- Проверять путь информации при проверке типов, чтобы гарантировать, что все типы выводятся принципиальным образом. При использовании именованных аргументов и/или полиморфных методов этот флаг необходим, чтобы будущие версии компилятора могли корректно выводить типы, даже если внутренние алгоритмы изменятся. Все программы, принимаемые в режиме -principal, также принимаются в режиме по умолчанию с эквивалентными типами, но с другими двоичными сигнатурами; при этом проверка типов может замедлиться. Тем не менее перед публикацией исходного кода рекомендуется один раз использовать этот параметр.
- -rectypes
- Разрешить произвольные рекурсивные типы при проверке типов. По умолчанию поддерживаются только рекурсивные типы, в которых рекурсия проходит через тип объекта.
- -safe-string
- Обеспечить разделение типов string и bytes, сделав строки доступными только для чтения. Это значение используется по умолчанию и применяется начиная с OCaml 5.0.
- -safer-matching
- Не использовать информацию о типах для оптимизации сопоставления с образцом. Это позволяет обнаруживать ошибки сопоставления, даже если сопоставление с образцом было ошибочно признано исчерпывающим. Это влияет только на компиляцию GADT и полиморфных вариантов.
- -short-paths
- Если тип доступен по нескольким путям модулей, использовать самый короткий путь при выводе имени типа в выводимых интерфейсах, сообщениях об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с подчёркивания _ или содержащие двойное подчёркивание __, получают штраф +10 при вычислении длины.
- -stdin
- Читать стандартный ввод как файл скрипта, а не запускать интерактивный сеанс.
- -strict-sequence
- Требовать, чтобы левая часть каждой последовательности имела тип unit.
- -strict-formats
- Отклонять некорректные форматы, которые принимались устаревшими реализациями форматов. Используйте этот флаг, чтобы обнаружить и исправить такие некорректные форматы, поскольку будущие версии OCaml будут их отклонять.
- -unsafe
- Отключить проверку границ при обращении к массивам и строкам (конструкции v.(i) и s.[i]). Поэтому программы, скомпилированные с параметром -unsafe, работают быстрее, но небезопасны: при обращении программы к элементу массива или строки за пределами их границ может произойти что угодно.
- -unsafe-string
- Объединить типы string и bytes, сделав строки доступными для записи. Этот параметр предназначен для совместимости со старым исходным кодом и не должен использоваться в новом программном обеспечении. Начиная с OCaml 5.0 этот параметр всегда вызывает ошибку.
- -v
- Вывести номер версии компилятора и расположение каталога стандартной библиотеки, затем завершить работу.
- -verbose
- Выводить все внешние команды перед их выполнением. Полезно для отладки проблем с библиотеками C.
- -version
- Вывести строку версии и завершить работу.
- -vnum
- Вывести краткий номер версии и завершить работу.
- -no-version
- Не выводить при запуске баннер с информацией о версии.
- -w warning-list
- Включить, отключить или пометить как фатальные предупреждения, указанные в аргументе warning-list. Каждое предупреждение можно включить или отключить, а также пометить как фатальное или нефатальное. Если предупреждение отключено, оно не отображается и никак не влияет на компиляцию (даже если оно фатальное). Если предупреждение включено, компилятор отображает его обычным образом всякий раз, когда исходный код вызывает его. Если оно включено и является фатальным, после его отображения компилятор также завершится с ошибкой.
Аргумент warning-list представляет собой последовательность спецификаторов предупреждений без разделителей между ними. Спецификатором предупреждения может быть одно из следующих значений:
- +num
- Включить предупреждение с номером num.
- -num
- Отключить предупреждение с номером num.
- @num
- Включить предупреждение с номером num и пометить его как фатальное.
- +num1..num2
- Включить предупреждения в указанном диапазоне.
- -num1..num2
- Отключить предупреждения в указанном диапазоне.
- @num1..num2
- Включить предупреждения в указанном диапазоне и пометить их как фатальные.
- +letter
- Включить набор предупреждений, соответствующий letter. Буква может быть прописной или строчной.
- -letter
- Отключить набор предупреждений, соответствующий letter. Буква может быть прописной или строчной.
- @letter
- Включить набор предупреждений, соответствующий letter, и пометить их как фатальные. Буква может быть прописной или строчной.
- uppercase-letter
- Включить набор предупреждений, соответствующий uppercase-letter.
- lowercase-letter
- Отключить набор предупреждений, соответствующий lowercase-letter.
Кроме того, в warning-list можно указать одно предупреждение по его мнемоническому имени (см. ниже), например:
- +name
- Включить предупреждение name.
- -name
- Отключить предупреждение name.
- @name
- Включить предупреждение name и пометить его как фатальное.
Номера, буквы и имена предупреждений, которые в данный момент не определены, игнорируются. Список предупреждений приведён ниже (имя после каждого номера — мнемоническое имя соответствующего предупреждения).
- 1 comment-start
- Подозрительно выглядящий маркер начала комментария.
- 2 comment-not-end
- Подозрительно выглядящий маркер окончания комментария.
- 3
- Устаревший синоним предупреждения «deprecated».
- 4 fragile-match
- Ненадёжное сопоставление с образцом: сопоставление, которое останется полным, даже если к одному из сопоставляемых вариантных типов добавить дополнительные конструкторы.
- 5 ignored-partial-application
- Функция применена не полностью: выражение, результат которого имеет функциональный тип и игнорируется.
- 6 labels-omitted
- Метка пропущена при применении функции.
- 7 method-override
- Метод переопределён.
- 8 partial-match
- Неполное сопоставление: в сопоставлении с образцом отсутствуют варианты.
- 9 missing-record-field-pattern
- В образце записи отсутствуют поля.
- 10 non-unit-statement
- Выражение в левой части последовательности не имеет тип unit и не является функцией (см. предупреждение 5).
- 11 redundant-case
- Избыточный вариант в сопоставлении с образцом (неиспользуемый вариант сопоставления).
- 12 redundant-subpat
- Избыточный подобразец в сопоставлении с образцом.
- 13 instance-variable-override
- Переменная экземпляра переопределена.
- 14 illegal-backslash
- Недопустимая escape-последовательность с обратной косой чертой в строковой константе.
- 15 implicit-public-methods
- Приватный метод неявно стал публичным.
- 16 unerasable-optional-argument
- Неудаляемый необязательный аргумент.
- 17 undeclared-virtual-method
- Необъявленный виртуальный метод.
- 18 not-principal
- Непринципиальный тип.
- 19 non-principal-labels
- Тип без свойства принципиальности.
- 20 ignored-extra-argument
- Неиспользуемый аргумент функции.
- 21 nonreturning-statement
- Оператор, не возвращающий управление.
- 22 preprocessor
- Предупреждение препроцессора.
- 23 useless-record-with
- Бесполезная конструкция записи with.
- 24 bad-module-name
- Некорректное имя модуля: имя исходного файла не является допустимым именем модуля OCaml.
- 25
- Игнорируется: теперь входит в предупреждение 8.
- 26 unused-var
- Подозрительная неиспользуемая переменная: неиспользуемая переменная, связанная с помощью let или as и не начинающаяся с символа подчёркивания (_).
- 27 unused-var-strict
- Безобидная неиспользуемая переменная: неиспользуемая переменная, не связанная ни с помощью let, ни с помощью as и не начинающаяся с символа подчёркивания (_).
- 28 wildcard-arg-to-constant-constr
- Образец-подстановочный знак передан как аргумент конструктору-константе.
- 29 eol-in-string
- Неэкранированный конец строки в строковой константе (непереносимый код).
- 30 duplicate-definitions
- Две метки или конструктора с одинаковыми именами объявлены в двух взаимно рекурсивных типах.
- 31 module-linked-twice
- Модуль дважды скомпонован в одном исполняемом файле. Игнорируется: теперь это безусловная ошибка (начиная с 5.1).
- 32 unused-value-declaration
- Неиспользуемое объявление значения. (начиная с 4.00)
- 33 unused-open
- Неиспользуемый оператор open. (начиная с 4.00)
- 34 unused-type-declaration
- Неиспользуемое объявление типа. (начиная с 4.00)
- 35 unused-for-index
- Неиспользуемый индекс цикла for. (начиная с 4.00)
- 36 unused-ancestor
- Неиспользуемая переменная предка. (начиная с 4.00)
- 37 unused-constructor
- Неиспользуемый конструктор. (начиная с 4.00)
- 38 unused-extension
- Неиспользуемый конструктор расширения. (начиная с 4.00)
- 39 unused-rec-flag
- Неиспользуемый флаг rec. (начиная с 4.00)
- 40 name-out-of-scope
- Имя конструктора или метки использовано вне области видимости. (начиная с 4.01)
- 41 ambiguous-name
- Неоднозначное имя конструктора или метки. (начиная с 4.01)
- 42 disambiguated-name
- Разрешена неоднозначность имени конструктора или метки (предупреждение о совместимости). (начиная с 4.01)
- 43 nonoptional-label
- Необязательная метка применена как обязательная. (начиная с 4.01)
- 44 open-shadow-identifier
- Оператор open затеняет уже объявленный идентификатор. (начиная с 4.01)
- 45 open-shadow-label-constructor
- Оператор open затеняет уже объявленную метку или конструктор. (начиная с 4.01)
- 46 bad-env-variable
- Ошибка в переменной окружения. (начиная с 4.01)
- 47 attribute-payload
- Недопустимая полезная нагрузка атрибута. (начиная с 4.02)
- 48 eliminated-optional-arguments
- Неявное устранение необязательных аргументов. (начиная с 4.02)
- 49 no-cmi-file
- Отсутствует файл cmi при поиске псевдонима модуля. (начиная с 4.02)
- 50 unexpected-docstring
- Неожиданный комментарий документации. (начиная с 4.03)
- 51 wrong-tailcall-expectation
- Вызов функции аннотирован некорректным атрибутом @tailcall. (начиная с 4.03)
- 52 fragile-literal-pattern (см. 13.5.3)
- Ненадёжный образец-константа. (начиная с 4.03)
- 53 misplaced-attribute
- Атрибут не может находиться в данном контексте. (начиная с 4.03)
- 54 duplicated-attribute
- Атрибут используется в выражении более одного раза. (начиная с 4.03)
- 55 inlining-impossible
- Встраивание невозможно. (начиная с 4.03)
- 56 unreachable-case
- Недостижимый вариант в сопоставлении с образцом (на основании информации о типах). (начиная с 4.03)
- 57 ambiguous-var-in-pattern-guard (см. 13.5.4)
- Неоднозначные переменные в or-образцах с защитным условием. (начиная с 4.03)
- 58 no-cmx-file
- Отсутствует файл cmx. (начиная с 4.03)
- 59 flambda-assignment-to-non-mutable-value
- Присваивание неизменяемому значению. (начиная с 4.03)
- 60 unused-module
- Неиспользуемое объявление модуля. (начиная с 4.04)
- 61 unboxable-type-in-prim-decl
- Нераспаковываемый тип в объявлении примитива. (начиная с 4.04)
- 62 constraint-on-gadt
- Ограничение типа в объявлении типа GADT. (начиная с 4.06)
- 63 erroneous-printed-signature
- Ошибочно выведенная сигнатура. (начиная с 4.08)
- 64 unsafe-array-syntax-without-parsing
- Параметр -unsafe использован с препроцессором, возвращающим синтаксическое дерево. (начиная с 4.08)
- 65 redefining-unit
- Объявление типа, определяющее новый конструктор «()». (начиная с 4.08)
- 66 unused-open-bang
- Неиспользуемый оператор open!. (начиная с 4.08)
- 67 unused-functor-parameter
- Неиспользуемый параметр функтора. (начиная с 4.10)
- 68 match-on-mutable-state-prevent-uncurry
- Сопоставление с образцом, зависящее от изменяемого состояния, препятствует устранению каррирования оставшихся аргументов. (начиная с 4.12)
- 69 unused-field
- Неиспользуемое поле записи. (начиная с 4.13)
- 70 missing-mli
- Отсутствует файл интерфейса. (начиная с 4.13)
- 71 unused-tmc-attribute
- Неиспользуемый атрибут @tail_mod_cons. (начиная с 4.14)
- 72 tmc-breaks-tailcall
- Преобразование @tail_mod_cons превращает хвостовой вызов в нехвостовой. (начиная с 4.14)
- 73 generative-application-expects-unit
- Генеративный функтор применён к пустой структуре (struct end), а не к (). (начиная с 5.1)
- 74 degraded-to-partial-match
- Сопоставление с образцом скомпилировано как неполное, хотя выглядит полным. (начиная с 5.3)
- 75 unnecessarily-partial-tuple-pattern
- Образец кортежа заканчивается на .., хотя полностью соответствует ожидаемому типу. (начиная с 5.4)
- A
- все предупреждения
- C
- предупреждения 1, 2.
- D
- Псевдоним предупреждения 3.
- E
- Псевдоним предупреждения 4.
- F
- Псевдоним предупреждения 5.
- K
- предупреждения 32, 33, 34, 35, 36, 37, 38, 39.
- L
- Псевдоним предупреждения 6.
- M
- Псевдоним предупреждения 7.
- P
- Псевдоним предупреждения 8.
- R
- Псевдоним предупреждения 9.
- S
- Псевдоним предупреждения 10.
- U
- предупреждения 11, 12.
- V
- Псевдоним предупреждения 13.
- X
- предупреждения 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30.
- Y
- Псевдоним предупреждения 26.
- Z
- Псевдоним предупреждения 27.
По умолчанию задано значение -w +a-4-7-9-27-29-30-32..42-44-45-48-50-60-66..70-74. Оно отображается командой -help. Обратите внимание, что предупреждения 5 и 10 возникают не всегда — это зависит от внутренних механизмов проверки типов.
- -warn-error warning-list
- Пометить как фатальные предупреждения, указанные в аргументе warning-list. Компилятор завершится с ошибкой при выдаче одного из этих предупреждений. Аргумент warning-list имеет то же значение, что и для параметра -w: знак + (или прописная буква) помечает соответствующие предупреждения как фатальные, знак - (или строчная буква) снова делает их нефatalальными предупреждениями, а знак @ одновременно включает соответствующие предупреждения и помечает их как фатальные.
Примечание: не рекомендуется использовать наборы предупреждений (то есть буквы) в качестве аргументов -warn-error в рабочем коде, так как это может нарушить сборку при добавлении новых предупреждений в будущих версиях OCaml.
По умолчанию задано значение -warn-error -a (ни одно предупреждение не является фатальным).
- -warn-help
- Показать описания всех доступных номеров предупреждений.
- - file
- Использовать file как имя файла сценария, даже если оно начинается с дефиса (-).
- -help или --help
- Вывести краткую сводку по использованию и завершить работу.
Unix: Также используются следующие переменные окружения:
- OCAMLTOP_INCLUDE_PATH
- Дополнительные каталоги для поиска файлов скомпилированного объектного кода (.cmi, .cmo и .cma). Указанные каталоги проверяются слева направо после поиска в каталогах подключаемых файлов, указанных в командной строке с помощью -I. Доступна начиная с OCaml 4.08.
- OCAMLTOP_UTF_8
- При выводе строковых значений байты, отличные от ASCII ( > \0x7E ), выводятся в виде десятичной escape-последовательности, если для OCAMLTOP_UTF_8 задано значение false. В противном случае они выводятся без экранирования.
- TERM
- При выводе сообщений об ошибках система верхнего уровня пытается визуально подчеркнуть место ошибки. Она проверяет переменную TERM, чтобы определить тип терминала вывода, и ищет его возможности в базе данных терминалов.
- XDG_CONFIG_HOME, HOME, XDG_CONFIG_DIRS
- Процедура поиска файла инициализации (см. выше).
2 Директивы верхнего уровня
Следующие директивы управляют поведением системы верхнего уровня, загружают файлы в память и отслеживают выполнение программы.
Примечание: все директивы начинаются с символа # (решётки). Этот символ # нужно вводить перед директивой; его не следует путать с приглашением #, отображаемым интерактивным циклом. Например, ввод #quit;; завершит цикл верхнего уровня, а ввод quit;; приведёт к ошибке «несвязанное значение quit».
- Общие сведения
-
- #help;;
- Выводит список всех доступных директив, при необходимости указывая соответствующий тип аргумента.
- #quit;;
- Выходит из интерактивного цикла и завершает команду ocaml.
- Загрузка кода
-
- #cd "dir-name";;
- Изменяет текущий рабочий каталог.
- #directory "dir-name";;
- Добавляет указанный каталог в список каталогов, в которых выполняется поиск исходных и скомпилированных файлов.
- #remove_directory "dir-name";;
- Удаляет указанный каталог из списка каталогов, в которых выполняется поиск исходных и скомпилированных файлов. Ничего не делает, если в списке нет указанного каталога.
- #load "file-name";;
- Загружает в память объектный файл с байт-кодом (файл .cmo) или файл библиотеки (файл .cma), созданный пакетным компилятором ocamlc.
- #load_rec "file-name";;
- Загружает в память объектный файл с байт-кодом (файл .cmo) или файл библиотеки (файл .cma), созданный пакетным компилятором ocamlc. При загрузке объектного файла, зависящего от других модулей, которые ещё не загружены, выполняется поиск файлов .cmo этих модулей и их рекурсивная загрузка. Порядок загрузки не определён.
- #use "file-name";;
- Читает, компилирует и выполняет фразы исходного кода из указанного файла. Это текстовое включение: фразы обрабатываются так, как если бы они были введены в стандартный ввод. Чтение файла прекращается при первой обнаруженной ошибке.
- #use_output "command";;
- Выполняет команду и обрабатывает её вывод так, как если бы он был записан в файл и передан директиве #use.
- #mod_use "file-name";;
- Аналогична #use, но также оборачивает код в модуль верхнего уровня, имя которого совпадает с именем файла без расширения, записанным с заглавной буквы, согласно семантике компилятора.
Для директив, принимающих имена файлов в качестве аргументов, если указанное имя файла не содержит каталога, поиск файла выполняется в следующих каталогах:
- В режиме сценария — в каталоге, содержащем выполняемый в данный момент сценарий; в интерактивном режиме — в текущем рабочем каталоге.
- В каталогах, добавленных директивой #directory.
- В каталогах, указанных в командной строке с помощью параметров -I.
- В каталоге стандартной библиотеки.
- Запросы к окружению
-
- #show_class class-path;;
- #show_class_type class-path;;
- #show_exception ident;;
- #show_module module-path;;
- #show_module_type modtype-path;;
- #show_type typeconstr;;
- #show_val value-path;;
- Выводит сигнатуру соответствующего компонента.
- #show ident;;
- Выводит сигнатуры компонентов с именем ident во всех перечисленных выше категориях.
- Форматирование вывода
-
- #install_printer printer-name;;
- Эта директива регистрирует функцию с именем printer-name (путь к значению) в качестве функции вывода для значений, типы которых соответствуют типу аргумента этой функции. Иными словами, интерактивный цикл будет вызывать printer-name, когда ему потребуется вывести такое значение.
Функция вывода printer-name должна иметь тип Format.formatter -> t -> unit, где t — тип выводимых значений. Она должна выводить текстовое представление значения типа t в заданный форматтер, используя функции библиотеки Format. Для обеспечения обратной совместимости printer-name также может иметь тип t -> unit и в этом случае должна выводить данные в стандартный форматтер, однако такое использование объявлено устаревшим.
- #print_depth n;;
- Ограничивает вывод значений максимальной глубиной n. Части значений, глубина которых превышает n, выводятся как ... (многоточие).
- #print_length n;;
- Ограничивает количество выводимых узлов значения числом n. Оставшиеся части значений выводятся как ... (многоточие).
- #remove_printer printer-name;;
- Удаляет указанную функцию из таблицы функций вывода интерактивного цикла.
- Трассировка
-
- #trace function-name;;
- После выполнения этой директивы все вызовы функции с именем function-name будут «трассироваться». То есть для каждого вызова будут выводиться аргумент и результат, а также исключения, выходящие из функции и порождённые самой функцией или другой вызываемой ею функцией. Если функция каррирована, каждый аргумент выводится по мере его передачи функции.
- #untrace function-name;;
- Прекращает трассировку указанной функции.
- #untrace_all;;
- Прекращает трассировку всех функций, для которых она была включена.
- Параметры компилятора
-
- #debug bool;;
- Включает или отключает вставку отладочных событий. По умолчанию — true.
- #labels bool;;
- Игнорирует метки в типах функций, если аргумент равен false, или возвращает поведение по умолчанию (коммутативный стиль), если аргумент равен true.
- #ppx "file-name";;
- После синтаксического анализа передаёт абстрактное синтаксическое дерево команде препроцессора.
- #principal bool;;
- Если аргумент равен true, проверяет пути информации при проверке типов, чтобы убедиться, что все типы выведены главным образом. Если аргумент равен false, пути информации не проверяются.
- #rectypes;;
- Разрешает произвольные рекурсивные типы при проверке типов. Примечание: после включения этот параметр нельзя отключить, поскольку это привело бы к нарушению корректности системы типов.
- #warn_error "warning-list";;
- Считает ошибками предупреждения, включённые аргументом, а предупреждения, отключённые аргументом, — обычными предупреждениями.
- #warnings "warning-list";;
- Включает или отключает предупреждения в соответствии с аргументом.
3 Интерактивный цикл и система модулей
Фразы интерактивного цикла могут обращаться к идентификаторам, определённым в единицах компиляции, теми же способами, что и отдельно скомпилированные единицы: используя квалифицированные имена (Modulename.localname) либо конструкцию open и неквалифицированные имена (см. раздел 11.3).
Однако перед обращением к другой единице компиляции её реализация должна находиться в памяти. При запуске интерактивная система содержит реализации всех модулей стандартной библиотеки. Реализации пользовательских модулей можно загрузить с помощью описанной выше директивы #load. Обращение к единице, реализация которой не была предоставлена, приводит к ошибке Reference to undefined global `...'.
Обратите внимание, что команда open Mod лишь обращается к скомпилированному интерфейсу (файлу .cmi) модуля Mod, но не загружает его реализацию и не вызывает ошибку, если реализация Mod не была загружена. Ошибка «ссылка на неопределённый глобальный объект Mod» возникает только при выполнении определения значения или модуля, ссылающегося на Mod.
4 Типичные ошибки
В этом разделе описаны и объяснены наиболее часто встречающиеся сообщения об ошибках.
- Не удаётся найти файл filename
- Указанный файл не найден ни в текущем каталоге, ни в каталогах пути поиска.
Если filename имеет формат mod.cmi, это означает, что вы обратились к единице компиляции mod, но её скомпилированный интерфейс не найден. Решение: сначала скомпилируйте mod.mli или mod.ml, чтобы создать скомпилированный интерфейс mod.cmi.
Если filename имеет формат mod.cmo, это означает, что вы пытаетесь загрузить с помощью #load ещё не существующий объектный файл с байт-кодом. Решение: сначала скомпилируйте mod.ml.
Если ваша программа состоит из файлов в нескольких каталогах, эта ошибка также может появиться из-за того, что вы не указали каталоги для поиска. Решение: используйте директиву #directory, чтобы добавить нужные каталоги в путь поиска.
- Это выражение имеет тип t1, но используется с типом t2
- См. раздел 13.4.
- Ссылка на неопределённый глобальный объект mod
- Вы забыли загрузить в память реализацию модуля с помощью #load. См. раздел 14.3 выше.
5 Создание пользовательских интерактивных систем: ocamlmktop
Команда ocamlmktop создаёт интерактивные среды OCaml с предварительно загруженным при запуске пользовательским кодом.
Команда ocamlmktop принимает в качестве аргументов набор файлов .cmo и .cma и связывает их с объектными файлами, реализующими интерактивную среду OCaml. Типичное использование:
ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
Эта команда создаёт файл с байт-кодом mytoplevel, содержащий интерактивную систему OCaml и код из трёх файлов .cmo. Эту интерактивную среду можно запустить непосредственно:
./mytoplevel
Запускается обычный интерактивный цикл, но код из файлов foo.cmo, bar.cmo и gee.cmo уже загружен в память, как если бы вы ввели:
#load "foo.cmo";;
#load "bar.cmo";;
#load "gee.cmo";;
при запуске интерактивной среды. Однако модули Foo, Bar и Gee не открыты; если вы хотите этого добиться, вам нужно самостоятельно выполнить
open Foo;;
.
5.1 Параметры
Команда ocamlmktop распознаёт следующие параметры командной строки.
- -cclib libname
- Передаёт параметр -llibname компоновщику C при компоновке в режиме «пользовательской среды выполнения». См. соответствующий параметр ocamlc в главе 13.
- -ccopt option
- Передаёт указанный параметр компилятору C и компоновщику при компоновке в режиме «пользовательской среды выполнения». См. соответствующий параметр ocamlc в главе 13.
- -custom
- Выполняет компоновку в режиме «пользовательской среды выполнения». См. соответствующий параметр ocamlc в главе 13.
- -I directory
- Добавляет указанный каталог в список каталогов, в которых выполняется поиск скомпилированных объектных файлов (.cmo и .cma).
- -o exec-file
- Задаёт имя файла интерактивной среды, создаваемого компоновщиком. По умолчанию используется a.out.
6 Нативная интерактивная среда: ocamlnat (экспериментальная)
В этом разделе описан инструмент, который пока официально не поддерживается, но может оказаться полезным.
Код OCaml, выполняемый в традиционной интерактивной среде, обрабатывается интерпретатором байт-кода. Если требуется повысить производительность или протестировать программы, которые корректно выполняются только после компиляции в машинный код, вместо неё можно использовать нативную интерактивную среду.
В большинстве случаев нативная интерактивная среда не устанавливается вместе с остальными инструментами OCaml. В таких случаях необходимо собрать дистрибутив OCaml из исходного кода. В собранном дереве исходного кода дистрибутива можно выполнить make natruntop, чтобы собрать и запустить нативную интерактивную среду. (В качестве альтернативы можно использовать make ocamlnat, который выполняет только сборку.)
Если после сборки нативной интерактивной среды выполнить команду make install, программу ocamlnat (из каталога с исходным кодом или каталога установки) можно будет запускать напрямую, не используя make natruntop.
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/toplevel.html