2010-01-13 9 views
5

Así que estoy tratando de explorar las partes internas de Clojure y he encontrado algo que no estoy muy seguro de entender:Clojure rareza con Var.intern y RT.var

Desde el REPL, puedo acceder a RT .var ("clojure.core", "requiere") bien (esto se supone que devolver el var asociado con el símbolo "requerir" en el espacio de nombres "clojure.core"):

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

Sin embargo, si Intento acceder a él en lo que pensé que era de la misma manera (

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) 

Aparece un error que ya se requiere se refiere a algo que existe. Esto es muy extraño porque RT.var es lo mismo que Var.intern, excepto con los argumentos convertidos a un Espacio de nombre y un Símbolo, respectivamente.

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

Voy a hacer un poco más de excavación, pero estoy bastante perplejo en este caso. Ya he comprobado: 1. nil es lo mismo que nulo 2. Creé var2, que devuelve el argumento del espacio de nombres enviado a Var.intern, y var3, que devuelve el argumento del nombre enviado a Var.intern. Luego paso esos dos 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) 

¿Podría ser esto un error?

Respuesta

4

Esto funciona bien:

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

Symbol/intern obras también: la

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

AH sí ... Estaba usando clojure.main en lugar de clojure.core. ¡Gracias! – Jieren

+1

¡De nada! A propósito, utilicé 'Symbol/create' en lugar de' Symbol/intern', pero 'intern' también funciona ... Creo que será mejor editarlo, para que no confunda a algún visitante futuro con esta pregunta. :-) –

+2

Symbol.intern() y Symbol.create() hacen básicamente lo mismo que estos días. Originalmente, Create esperaría cadena interna como argumento, pero este comportamiento se modificó. Rich estaba pensando en deshacerse de create() en algún momento en el futuro. – liwp

0

de la réplica es sólo clojure.main, por lo que puede no clojure.main pasante/requerir en un REPL, pero clojure .core/require, ¡creo!