Предварительно определить переменные перед загрузкой пространства имен - PullRequest
3 голосов
/ 27 августа 2011

У меня есть пространство имен, называемое some.core, со следующим:

(ns some.core)
(defonce name-of-something :a)

, затем из плагина leiningen я хотел бы предварительно определить имя чего-либо перед загрузкой пространства имен, чтобы при загрузке пространства именоно уже определено, defonce не определит его.


    (eval-in-project project
                     `(do (create-ns 'some.core)
                          (intern 'some.core 'name-of-something :b)))

, но с учетом вышеизложенного я получаю

Can't intern namespace-qualified symbol

error.

Ответы [ 2 ]

5 голосов
/ 27 августа 2011

(Обновлено с учетом комментариев ниже. Я оставляю исходный ответ под горизонтальным правилом, чтобы не удалять контекст комментариев.)

TL; исправление DR:

`(do ... (intern 'some.core '~'name-of-something :b))
                          ; ^- note the '~'

Проблема в том, что форма (do ...) имеет синтаксические кавычки (заключенные в кавычки, а не в одиночные кавычки), поэтому символы внутри нее заменяются вариантами, определенными для пространства имен (после разрешения для определения, какое пространство имен они должен быть квалифицирован с). Это исключает символы, которые уже определены в пространстве имен, а также символы, содержащие точку.

Проблемный символ в приведенном выше: name-of-something - без точек и без оговорок. Чтобы исправить ситуацию, вы можете заменить 'name-of-something на '~'name-of-something; первая кавычка включается в вывод синтаксической кавычки, тильда приводит к тому, что значение формы, следующее непосредственно за ней, включается в расширение области синтаксической кавычки, и, наконец, 'name-of-something является самой формой, вычисляя до ( безусловный) символ name-of-something:

Если отменить кавычки не нужно, замена обратного кавычка одинарной кавычкой также решит проблему. (Окончательное решение - упомянутое для полноты - будет создать форму вручную: (list 'do ...).)


(Оригинальный ответ следует.)

Вам необходимо изменить обратный кавычки на одинарные кавычки:

`(do (create-ns 'some.core) ...)
; change to
'(do (create-ns 'some.core) ...)
^- note the quote

Что происходит с обратным трюком, или «цитатой синтаксиса», так это то, что 'name-of-something превращается в 'current-namespace/name-of-something, в результате чего intern жалуется. (Обратите внимание, что some.core остается нетронутым - я полагаю, из-за магической обработки точек в символах. Другие символы - do, create-ns и intern - также заменяются вариантами, определенными для пространства имен, но это не вызывает никаких проблем.)

0 голосов
/ 30 августа 2011

Другой вариант - сначала загрузить пространство имен с помощью defonce, а затем изменить его с помощью alter-var-root.

Оба варианта - довольно сумасшедшие обходные пути, но то, что вы спрашиваете, с самого начала довольно безумно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...