Исключить java.lang. * В пространстве имен Clojure - PullRequest
8 голосов
/ 18 марта 2012

Есть ли возможность исключить имена классов из java.lang в пространстве имен Clojure?

Мне нужно использовать переменные, такие как Byte и String, и здесь мне приходят в голову имена классов java.lang.

может быть что-то вроде (ns my-ns (: исключить java.lang))?

Ответы [ 3 ]

9 голосов
/ 18 марта 2012

Если вы используете полное имя, нет никакой двусмысленности.Например:

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

После того, как вы определили Байт таким образом, Байт разрешит ваше определение без необходимости уточнять имя

user=> Byte
0
1 голос
/ 19 марта 2012

Это, конечно, возможно, если вы вручную удалите встроенное отображение в java.lang.String перед созданием собственного:

$ 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

Я повторю некоторые другие комментарии, которые определяют что-тоnamed String вряд ли сделает вашу жизнь приятной / удобной.

1 голос
/ 18 марта 2012

Я не знаю однозначного ответа на ваш вопрос, но мое обоснованное предположение состоит в том, что вы не можете без изменения самой clojure. Вот мой анализ:

Символ String встроен в clojure/lang/Namespace.java как часть отображений по умолчанию (см. Конструктор Namespace в этом классе, который ссылается на DEFAULT_MAPPINGS в классе clojure/lang/RT.java). Стажировка означает наличие ключа в переменной-члене mappings класса Namespace. Результатом этого является то, что каждое пространство имен начинается с String, сопоставленного с String.class (см. Строку 77 в RT.java в clojure 1.4.0).

В макросе ns вы можете сделать что-то вроде:

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

но все, что делает, это пропускает код, который интернирует новые символы (см. Строку 3770 из clojure / core.clj в clojure 1.4.0), поэтому он не может ничего сделать, чтобы помочь вам удалить String из отображений пространства имен .

Наконец, если вы попытаетесь переопределить отображение для String с помощью чего-то вроде (defn String ...), компилятор будет жаловаться, потому что String.class не является экземпляром Var. Подробности смотрите в строке 6797 clojure / lang / Compiler.java в clojure 1.4.0).

...