2011-08-27 57 views
3

我有一個名爲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 

錯誤。

回答

5

(已更新至以下考慮意見,我離開原來的答覆下的水平線,以免刪除評論的上下文。)

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保持不變 - 由於對符號中的點進行了神奇的處理,我相信其他符號 - docreate-nsintern - 也會替換爲符合命名空間限定的變體,但這不會導致任何問題。 )

+0

但是我不能從上下文中傳遞變量:b實際上是從命令行讀取的 –

+0

在這種情況下,您可以用'〜'name-of-something'替換'something-of-something'。請注意「非引用」的代字號。 –

+0

與顎化的地方,它試圖評估名稱的東西,我無法解決符號 –

0

另一種方法是先用defonce加載命名空間,然後用alter-var-root改變它。

這兩個都是非常瘋狂的解決方法,但你要問的是非常瘋狂的開始。