summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-05-04 13:09:05 -0400
committerRich Hickey <richhickey@gmail.com>2010-05-04 13:09:05 -0400
commitab9a567faecc8cfde4625654fe9bb92988d7494d (patch)
tree2ea2afd298b1feedb10e9f6277f329006ee00dec
parent68a14c88d11555353bb471efd94ba7d40c2d5008 (diff)
last-one-in-wins for refers and interns, warns on replacement
-rw-r--r--src/jvm/clojure/lang/Compiler.java5
-rw-r--r--src/jvm/clojure/lang/Namespace.java28
2 files changed, 29 insertions, 4 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 90da5d97..1506cb27 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -407,8 +407,9 @@ static class DefExpr implements Expr{
if(!v.ns.equals(currentNS()))
{
if(sym.ns == null)
- throw new Exception("Name conflict, can't def " + sym + " because namespace: " + currentNS().name +
- " refers to:" + v);
+ v = currentNS().intern(sym);
+// throw new Exception("Name conflict, can't def " + sym + " because namespace: " + currentNS().name +
+// " refers to:" + v);
else
throw new Exception("Can't create defs outside of current ns");
}
diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java
index 7849e04c..34a5c50d 100644
--- a/src/jvm/clojure/lang/Namespace.java
+++ b/src/jvm/clojure/lang/Namespace.java
@@ -14,6 +14,7 @@ package clojure.lang;
import java.io.ObjectStreamException;
import java.io.Serializable;
+import java.io.PrintWriter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
@@ -66,7 +67,23 @@ 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);
+// throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
+
+ if(v == null)
+ v = new Var(this, sym);
+
+ warnOnReplace(sym, o, v);
+
+
+ while(!mappings.compareAndSet(map, map.assoc(sym, v)))
+ map = getMappings();
+
+ return v;
+}
+
+private void warnOnReplace(Symbol sym, Object o, Object v){
+ ((PrintWriter) RT.ERR.deref()).println("WARNING: " + sym + " already refers to: " + o + " in namespace: " + name
+ + ", being replaced by: " + v);
}
Object reference(Symbol sym, Object val){
@@ -85,7 +102,14 @@ Object reference(Symbol sym, Object val){
if(o == val)
return o;
- throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
+// throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
+ warnOnReplace(sym, o, val);
+
+ while(!mappings.compareAndSet(map, map.assoc(sym, val)))
+ map = getMappings();
+
+ return val;
+
}
public static boolean areDifferentInstancesOfSameClassName(Class cls1, Class cls2) {