diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-05-04 13:09:05 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-05-04 13:09:05 -0400 |
commit | ab9a567faecc8cfde4625654fe9bb92988d7494d (patch) | |
tree | 2ea2afd298b1feedb10e9f6277f329006ee00dec | |
parent | 68a14c88d11555353bb471efd94ba7d40c2d5008 (diff) |
last-one-in-wins for refers and interns, warns on replacement
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 5 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Namespace.java | 28 |
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) { |