2012-03-18 9 views
7

¿Existe la posibilidad de excluir los nombres de clase de java.lang en un espacio de nombres Clojure?Excluir java.lang. * En el espacio de nombres Clojure

Necesito usar variables como Byte y String, y aquí los nombres de clase java.lang entran en mi camino.

tal vez algo así como (ns my-ns (: exclude java.lang))?

+1

El espacio de nombre clojure.core depende de muchas cosas en java.lang. *, Así que no estoy seguro si es una buena idea redefinir esas clases, incluso si es posible. Por ejemplo, 'str',' keyword', 'for', son funciones y macros que usan la clase' java.lang.String'. –

+1

Creo que esto no debería ser un problema, siempre que no sean macros y utilicen "String" en el tiempo de ejecución. También puedo excluir las funciones de clojure.core que utilizan otras funciones, ya que están totalmente calificadas internamente. Entonces, usar String, cuando se usa internamente java.lang.String no debería ser un problema. –

+0

Por curiosidad, ¿por qué necesitas nombrar tus variables 'Byte' y' String'? – Gert

Respuesta

8

Si usa el nombre completo, no hay ambigüedad. Por ejemplo:

user=> (def user/Byte (java.lang.Byte/decode "0")) 
#'user/Byte 

Tras definir los bytes de esta manera, Byte resolverá a su definición sin la necesidad de calificar el nombre

user=> Byte 
0 
1

No sé la respuesta definitiva a su pregunta, pero mi conjetura es que no se puede sin modificar clojure sí mismo. Aquí está mi análisis:

El símbolo String está internado en clojure/lang/Namespace.java como parte de las asignaciones predeterminadas (véase el constructor Namespace en esa clase, que hace referencia a DEFAULT_MAPPINGS en la clase clojure/lang/RT.java). Internar significa que hay una clave en la variable miembro mappings de la clase Namespace. El resultado de esto es que cada espacio de nombre comienza con String mapeado a String.class (vea la línea 77 de RT.java en clojure 1.4.0).

En el ns macro, puede hacer algo como:

(ns my-ns 
    (:refer-clojure :exclude [<mapping to exclude>])) 

pero todo lo que hace es saltarse el código que los internos nuevos símbolos (véase la línea 3770 de clojure/core.clj en clojure 1.4.0) , por lo que no puede hacer nada para ayudarlo a eliminar String de las asignaciones del espacio de nombres.

Por último, si se intenta redefinir la asignación para String con algo así como un (defn String ...) el compilador se quejará porque String.class no es una instancia de Var. Vea la línea 6797 de clojure/lang/Compiler.java en clojure 1.4.0 para más detalles).

1

Esto es ciertamente posible si se quita manualmente el incorporada en la asignación de java.lang.String antes de crear su propia:

$ cake repl 
repl-1=> (def String 1) 
java.lang.Exception: Expecting var, but String is mapped to class java.lang.String (NO_SOURCE_FILE:1) 
repl-1=> (ns-unmap *ns* 'String) 
nil 
repl-1=> (def String 1) 
#'repl-1/String 
repl-1=> String 
1 

voy a repetir algunas de los otros comentarios, sin embargo, que la definición algo llamado String no hará que su vida sea agradable/conveniente.

Cuestiones relacionadas