summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-05-21 10:23:17 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-05-22 13:55:10 -0400
commit095734ac5064329c03eba65ade873993a890201e (patch)
treefeb6f21c426b3d4ccbf4323e46d96931169f7ff0
parent65ae4928119a50e892bc33e8cbb47a82ebef98ee (diff)
last var wins only for clojure.core, #332
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/main.clj2
-rw-r--r--src/jvm/clojure/lang/Namespace.java14
-rw-r--r--test/clojure/test_clojure/rt.clj31
3 files changed, 39 insertions, 8 deletions
diff --git a/src/clj/clojure/main.clj b/src/clj/clojure/main.clj
index e607440c..19aea435 100644
--- a/src/clj/clojure/main.clj
+++ b/src/clj/clojure/main.clj
@@ -194,7 +194,7 @@
(catch Throwable e
(caught e)
(set! *e e)))
- (use 'clojure.repl)
+ (use '[clojure.repl :only (source-fn source apropos dir-fn dir)])
(prompt)
(flush)
(loop []
diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java
index 383719f5..4c557a9a 100644
--- a/src/jvm/clojure/lang/Namespace.java
+++ b/src/jvm/clojure/lang/Namespace.java
@@ -66,12 +66,10 @@ public Var intern(Symbol sym){
if(o instanceof Var && ((Var) o).ns == this)
return (Var) o;
-// throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
-
if(v == null)
v = new Var(this, sym);
- warnOnReplace(sym, o, v);
+ warnOrFailOnReplace(sym, o, v);
while(!mappings.compareAndSet(map, map.assoc(sym, v)))
@@ -80,7 +78,12 @@ public Var intern(Symbol sym){
return v;
}
-private void warnOnReplace(Symbol sym, Object o, Object v){
+private void warnOrFailOnReplace(Symbol sym, Object o, Object v){
+ if (o instanceof Var) {
+ if (((Var)o).ns != RT.CLOJURE_NS) {
+ throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
+ }
+ }
RT.errPrintWriter().println("WARNING: " + sym + " already refers to: " + o + " in namespace: " + name
+ ", being replaced by: " + v);
}
@@ -101,8 +104,7 @@ Object reference(Symbol sym, Object val){
if(o == val)
return o;
-// throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
- warnOnReplace(sym, o, val);
+ warnOrFailOnReplace(sym, o, val);
while(!mappings.compareAndSet(map, map.assoc(sym, val)))
map = getMappings();
diff --git a/test/clojure/test_clojure/rt.clj b/test/clojure/test_clojure/rt.clj
index 3a63c029..e72d4e06 100644
--- a/test/clojure/test_clojure/rt.clj
+++ b/test/clojure/test_clojure/rt.clj
@@ -30,6 +30,14 @@
~@body
(str s#))))
+(defn temp-ns
+ "Create and return a temporary ns, using clojure.core + uses"
+ [& uses]
+ (binding [*ns* *ns*]
+ (in-ns (gensym))
+ (apply clojure.core/use 'clojure.core uses)
+ *ns*))
+
(defmacro eval-in-temp-ns [form]
`(binding [*ns* *ns*]
(in-ns (gensym))
@@ -45,7 +53,7 @@
(is (re-matches msg-re (with-err-print-writer (eval-in-temp-ns form))))))
(deftest error-messages
- (testing "binding a var that already refers to something"
+ (testing "binding a core var that already refers to something"
(should-print-err-message
#"WARNING: prefers already refers to: #'clojure.core/prefers in namespace: .*\n"
(defn prefers [] (throw (RuntimeException. "rebound!")))))
@@ -72,3 +80,24 @@
(is (contains? (meta #'example-var) :macro))
(.bindRoot #'example-var 0)
(is (not (contains? (meta #'example-var) :macro))))
+
+(deftest last-var-wins-for-core
+ (testing "you can replace a core name, with warning"
+ (let [ns (temp-ns 'clojure.set)
+ replacement (gensym)]
+ (with-err-string-writer (intern ns 'prefers replacement))
+ (is (= replacement @('prefers (ns-publics ns))))))
+ (testing "you cannot intern over an existing non-core name"
+ (let [ns (temp-ns 'clojure.set)
+ replacement (gensym)]
+ (is (thrown? IllegalStateException
+ (intern ns 'subset? replacement)))
+ (is (nil? ('subset? (ns-publics ns))))
+ (is (= #'clojure.set/subset? ('subset? (ns-refers ns))))))
+ (testing "you cannot refer over an existing non-core name"
+ (let [ns (temp-ns 'clojure.set)
+ replacement (gensym)]
+ (is (thrown? IllegalStateException
+ (.refer ns 'subset? #'clojure.set/intersection)))
+ (is (nil? ('subset? (ns-publics ns))))
+ (is (= #'clojure.set/subset? ('subset? (ns-refers ns)))))))