Clojure - REPL и точки входа main
Clojure

REPL и точки входа main

Пространство имен clojure.main

Пространство имен clojure.main предоставляет функции, которые позволяют запускать программы Clojure и открывать сеансы взаимодействия с помощью команды java.

clojure.main --help

Точка входа clojure.main/main принимает множество аргументов и флагов, как и описано в её справочном сообщении:

Использование: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*]

Без параметров или аргументов запускает интерактивный REPL (Read-Eval-Print Loop) - цикл считывания выражений и выдачи результатов.

init-opt:
-i, --init path Загрузить файл или ресурс
-e, --eval string Вычисляет выражение в строке; выводит значения не равные nil

main-opt:
-r, --repl Запустить REPL
path Запустить скрипт из файла или ресурса
- Запустить скрипт из стандартного ввода
-m, --main Пространство имен, в котором следует искать -main функцию для исполнения
-h, -?, --help Вывести это справочное сообщение и выйти

процесс работы:

- (TODO) Establishes thread-local bindings for commonly set!-able vars
- Входит в пространство имен user
- Устанавливает в *command-line-args* последовательность содержащую аргументы
командной строки после main-opt
- Запускает все init-opt по порядку
- Запускает REPL или скрипт если необходимо

Опции init-opt могут повторяться в произвольном количестве и порядке, но должны быть
перечислены до опций main-opt. Появление опции eval перед запуском repl
заглушает обычное приветствие REPL: "Clojure ~(clojure-version)".

Пути до файлов могут быть абсолютными или относительными в файловой системе или же относительными
к classpath. Classpath-относительные пути должны иметь префикс @ или @/

Запуск REPL

Простейший способ запустить repl - использование следующей команды в домашней директории Clojure:

java -cp clojure.jar clojure.main

Подсказка REPL покажет текущее пространство имен (*ns*), по-умолчанию - user.

В REPL доступны несколько специальных переменных:

  • *1, *2, *3 - хранят результат последних трех вычисленных выражений

  • *e - хранит последнее исключение.

Пространство имен clojure.repl содержит несколько полезных функций для изучения исходного кода и документации доступных функций:

  • doc - печатает информацию о переменной по её имени

  • find-doc - печатает информацию о переменных, чья документация или имя подходит под регулярное выражение

  • apropos - возвращает последовательность определений, подходящих под регулярное выражение

  • source - печатает исходный код для заданного знака

  • pst - печатает стек вызовов (print stack trace) для данного исключения, по-умолчанию - *e

Запуск скрипта

Чтобы выполнить скрипт-файл с Clojure кодом, нужно передать путь до скрипта в clojure.main как аргумент:

java -cp clojure.jar clojure.main /path/to/myscript.clj

Передача аргументов в скрипт

Чтобы передать аргументы в скрипт, их нужно записать как конечные аргументы при запуске clojure.main:

java -cp clojure.jar clojure.main /path/to/myscript.clj arg1 arg2 arg3

Аргументы будут предоставлены в вашей программе как последовательность строк, привязанных к переменной *command-line-args*:

*command-line-args* => ("arg1" "arg2" "arg3")

Запуск сервера

Эта возможность была добавлена в 1.8.0.

Clojure теперь позволяет запускать сервер в зависимости от системных параметров Java. Одно из возможных применений этого - запуск серверного REPL. Также сервера могут быть использованы, чтобы добавлять новый функционал в программы Clojure без изменения исходного кода.

Отдельный сервер будет запущен для каждого системного параметра вида "clojure.server.<имя сервера>". Значением аргумента должен быть ассоциативный массив с настройками этого сервера:

  • server-daemon - по-умолчанию true, соединения ожидаются в потоке-демоне или нет

  • address - хост или адрес, по-умолчанию - локальный

  • port - положительное целое число, обязательный параметр

  • accept - функция для обработки входящего соединения с указанием пространства имен, обязательный параметр

  • args - последовательность аргументов, которые нужно передать функции accept

  • bind-err - по-умолчанию true, привязывает поток ошибок *err* к выходному потоку соединения

  • client-daemon - по-умолчанию true, соединения обрабатываются в потоке-демоне или нет

Кроме того, существует функция repl, предназначенная специально для использования с серверами: clojure.core.server/repl.

Ниже приведен пример запуска сервера, обслуживаемого функцией repl. Этот параметр может быть добавлен при запуске к любой программе Clojure, чтобы она была способна принимать внешние соединения на порт 5555 и обрабатывать их с помощью REPL.

-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"

Например, с помощью telnet можно установить соединение с этим сервером:

$ telnet 127.0.0.1 5555
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
user=> (println "hello")
hello

Вы можете приказать серверу закрыть клиентское соединение с помощью специальной команды :repl/quit:

user=> :repl/quit
Connection closed by foreign host.

Смотри также:

Функции

Главная точка входа: clojure.main/main

Функция REPL: clojure.main/repl

Функция, устанавливающая переменные REPL для выполнения: clojure.main/with-bindings

Функция REPL, удобная для сервера: clojure.core.server/repl