我有一个名为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
错误。
答案 0 :(得分:5)
(已更新以考虑以下评论。我将原始答案保留在水平线规则下,以便不删除评论的上下文。)
TL; DR修复:
`(do ... (intern 'some.core '~'name-of-something :b))
; ^- note the '~'
问题是(do ...)
形式是语法引用的(引用反引号而不是单引号),因此其中的符号被命名空间限定的变体替换(在解析后确定哪个命名空间,他们应该合格)。这不包括已经命名空间限定的符号以及包含点的符号。
上面有问题的符号是name-of-something
- 无点且不合格。要纠正这种情况,您可以将'name-of-something
替换为'~'name-of-something
;第一个引用包含在syntax-quote的输出中,tilde使得紧随其后的表单的值被包含在语法引用区域的扩展中,最后'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
- 也是替换为名称空间限定的变体,但这不会导致任何问题。)
答案 1 :(得分:0)
另一个选择是首先使用defonce加载命名空间,然后使用alter-var-root更改它。
两者都是相当疯狂的解决方法,但你要问的是开始时非常疯狂。