2010-01-13 3 views
5

Così sto cercando di esplorare interni di Clojure e ho incontrato qualcosa che non sono del tutto sicuro di aver capito:Clojure stranezze con Var.intern e RT.var

Dal REPL, posso accedere RT .var ("clojure.core", "richiede") bene (questo dovrebbe restituire la var associato al simbolo "richiedere" nello spazio dei nomi "clojure.core"):

user=> (clojure.lang.RT/var "clojure.core" "require") 
#'clojure.core/require 

Tuttavia, se Provo ad accedervi in ​​quello che pensavo fosse allo stesso modo (

user=> (clojure.lang.Var/intern (clojure.lang.Namespace/findOrCreate (clojure.lang.Symbol/intern nil "clojure.main")) (clojure.lang.Symbol/intern nil "require")) 
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0) 

Ricevo un errore che richiede già si riferisce a qualcosa che esiste. Questo è molto strano perché RT.var è lo stesso di Var.intern, tranne che con gli argomenti convertiti rispettivamente in Namespace e Symbol.

static public Var var(String ns, String name){ 
    return Var.intern(Namespace.findOrCreate(Symbol.intern(null, ns)), Symbol.intern(null, name)); 
} 

Farò qualche altro scavo, ma sono abbastanza perplesso su questo. Ho già controllato: 1. nil è uguale a null 2. Ho creato var2, che restituisce l'argomento spazio dei nomi inviato a Var.intern e var3, che restituisce l'argomento nome inviato a Var.intern. Poi passo quei due a Var.intern:

user=> (clojure.lang.Var/intern 
(clojure.lang.RT/var2 "clojure.main" "require") 
(clojure.lang.RT/var3 "clojure.main" "require")) 
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0) 

Potrebbe essere un bug?

risposta

4

Questo funziona bene:

(clojure.lang.Var/intern 
(clojure.lang.Namespace/findOrCreate 
    (clojure.lang.Symbol/create "clojure.core")) 
(clojure.lang.Symbol/create "require")) 

Symbol/intern opere anche:

(clojure.lang.Var/intern 
(clojure.lang.Namespace/findOrCreate 
    (clojure.lang.Symbol/intern nil "clojure.core")) 
(clojure.lang.Symbol/intern nil "require")) 
+0

AH sì ... stavo usando clojure.main invece di clojure.core. Grazie! – Jieren

+1

Prego! Per inciso, ho usato 'Symbol/create' al posto di' Symbol/intern', ma anche 'intern' funziona ... Suppongo che sarà meglio modificarlo, per non confondere qualche visitatore futuro a questa domanda. :-) –

+2

Symbol.intern() e Symbol.create() fanno praticamente la stessa cosa per tutti i giorni. Originariamente creare si aspetterebbe una stringa interna come argomento, ma questo comportamento è stato modificato. Rich stava pensando di sbarazzarsi di create() ad un certo punto nel futuro. – liwp

0

Il REPL è proprio clojure.main, in modo che possiamo clojure.main non stagista/richiedere in un REPL, ma clojure .core/require, penso!