2012-03-18 9 views
7

Clojure名前空間のjava.langからクラス名を除外する可能性はありますか?Clojure名前空間のjava.lang。*を除外

私はByteやStringのような変数を使う必要があります。ここではjava.langクラス名が私のところに来ます。

(ns my-ns(:exclude java.lang))?

+1

clojure.coreネームスペースは、java.lang。*の中にたくさんのものがあるため、できるだけそれらのクラスを再定義することをお勧めしません。たとえば、 'str'、' keyword'、 'for'は' java.lang.String'クラスを使用する関数とマクロです。 –

+1

これはマクロではなく、実行時に "String"を使用する限り問題ではないと思います。また、内部的に完全修飾されているため、他の関数で使用されるclojure.core関数を除外することもできます。 Stringを使用すると、内部的にjava.lang.Stringが使用されているときに問題になることはありません。 –

+0

好奇心で、_why_変数の名前を 'Byte'と' String'にする必要がありますか? – Gert

答えて

8

完全修飾名を使用する場合、あいまいさはありません。たとえば:あなたは手動で削除する場合

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

あなたがこの方法でバイトを定義した後、バイトがせずに、あなたの定義に解決されます名前

user=> Byte 
0 
1

あなたの質問に対する決定的な答えはわかりませんが、私の推測では、クロージャー自体を変更することはできません。ここに私の分析です:

Stringシンボルがデフォルトのマッピング(clojure/lang/RT.javaクラスでDEFAULT_MAPPINGSを参照し、そのクラスでNamespaceコンストラクタを参照)の一環としてclojure/lang/Namespace.javaに抑留されています。インターンは、Namespaceクラスのメンバ変数mappingsにキーがあることを意味します。これの結末はです。すべてという名前空間は、(clojure 1.4.0のRT.javaの77行目を参照)にマップされたStringで始まります。マクロns

、あなたのような何かを行うことができます:

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

が、ないものはすべて、新しいシンボルをインターンコードを飛ばしている(Clojureの1.4.0でのClojure/core.cljの行3770を参照してください)ので、名前空間のマッピングからStringを削除するのに役立つものは何もできません。あなたは(defn String ...)コンパイラのようなものでStringのマッピングを再定義しようとすると、String.classVarのインスタンスではありませんので、

最後に、文句を言うでしょう。詳細については、clojure/lang/Compiler.javaの6797行目を参照してください)。

1

を修飾する必要性がこれは確かに可能です

$ 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 

私はいくつかの他のコメントをエコーし​​ますStringという名前のものはあなたの人生を楽しく便利にするものではありません。