В настоящее время я добавляю функциональные возможности существующему веб-приложению J2EE в контейнере Tomcat и пишу свои дополнения с помощью Clojure. Моя установка проста: я просто добавляю вызовы статических методов, сгенерированных clojure, и кодирую всю тяжелую работу со стороны clojure. Процесс сборки заключается в компиляции кода закрытия (lein uberjar
), а затем компиляции кода Java с этим jar-файлом в пути к классам.
В инициализации webapp у меня есть вызов сгенерированного класса, который запускает шикарный сервер с (swank/start-repl)
. Я хотел бы иметь возможность подключить мой слайм Aquamacs к этому серверу и работать с него в интерактивном режиме (до определенного момента я не буду пробовать ничего, что требует перекомпиляции на стороне Java). Но у меня есть ситуация, которую я не совсем понимаю. Если я сделаю \M-x slime-connect
, я получаю приглашение REPL (после уведомления об отсутствии подчиненного процесса lisp, что я думаю, это нормально, поскольку подчиненный процесс lisp работает вне управления emacs). Я могу отлично оценивать формы и даже проверять такие вещи, как my.own.namespace/my-var
. Однако, если я обращаюсь к файлу с уже скомпилированным кодом clojure, я не могу заставить слизь распознавать его как источник. Рассмотрим простой файл clojure:
(ns my.namespace
(:gen-class
:name my.namespace
:methods [#^{:static true} [testFunc [] void]]))
(def *secret* "shhhh")
(defn -testFunc []
(println (str "our secret is: " secret)))
Предполагая, что это было скомпилировано и включено в uberjar, загруженный веб-приложением, я могу оценить / проверить my.namespace/*secret*
. Но если я попытаюсь выполнить eval внутри буфера кода, Slime подумает, что я нахожусь в пространстве имен user
(что даже может иметь смысл!). Но теперь у меня остался один рабочий вариант - я должен оценить - одну за другой все формы в файле! \C-c \C-l
(загрузка исходного файла) ничего не сделает - очевидно, просто возвращает nil и больше ничего не выводит. Компиляция всего, кажется, делает именно это - она компилируется, показывает ошибки, если находит их, но не меняет мое пространство имен. И самым странным является \C-~
(пакет и каталог синхронизации), который, используя Common Lisp, делает именно то, что я хочу, но здесь он навсегда замораживает закрытый REPL.
Всегда есть возможность переключиться на REPL, набрать (in-ns 'my.namespace)
, и тогда все заработает правильно. Но это просто недостаточно практично, когда количество файлов clojure растет (поскольку пространство имен буфера кода не изменится автоматически!)
Тогда у меня вопрос, не хватает ли мне базовой команды / конфигурации - или есть очевидная причина, по которой такое поведение происходит как таковое.
C-c C-k
скомпилирует все формы в буфере файла в emacs, представит ошибки в этих формах и эффективно сделает динамически доступными переопределенные (и вновь определенные) формы (например, вызов webapp будет использовать этот недавно скомпилированный код). Извините за то, что не так ясно дал понять, как мог. - person Edgar Gonçalves   schedule 13.08.2010M-x swank-clojure-project
: при переключении на файловый буфер пространство имен автоматически изменяется, поэтому при оценке чего-то там не будет использоваться пространство именuser
. В качестве альтернативы, при компиляции / загрузке буфера с использованием _3 _ / _ 4_ следует оценивать все формы, включая начальный(ns ...)
, тем самым переключаясь на конкретное пространство имен и делая все последующие переменные принадлежащими ему. Разве это не ожидаемое поведение при стандартной настройке? (Я мог неправильно на это посмотреть ...) - person Edgar Gonçalves   schedule 13.08.2010