summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMeikel Brandmeyer <mb@kotka.de>2009-08-08 22:20:57 +0200
committerChouser <chouser@n01se.net>2009-09-28 12:26:26 -0400
commit110b9c2eb8a128d837e6e620efc7e1c4e33feb82 (patch)
tree6d8e64f6984d2104e1709b9943dcd8ff148e90ef /src
parentf4294d876cfc5b72650a2d5eab73757709d92b85 (diff)
Added public thread-local bindings interface
Added push-thread-bindings, pop-thread-bindings and get-thread-bindings to interface with clojure.lang.Var for thread-local bindings. Modified binding to use the new interface. Fixes #169 Signed-off-by: Chouser <chouser@n01se.net>
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index c32d4362..b87286eb 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1191,6 +1191,34 @@
(let [~form temp#]
~@body)))))
+(defn push-thread-bindings
+ "WARNING: This is a low-level function. Prefer high-level macros like
+ binding where ever possible.
+
+ Takes a map of Var/value pairs. Binds each Var to the associated value for
+ the current thread. Each call *MUST* be accompanied by a matching call to
+ pop-thread-bindings wrapped in a try-finally!
+
+ (push-thread-bindings bindings)
+ (try
+ ...
+ (finally
+ (pop-thread-bindings)))"
+ [bindings]
+ (clojure.lang.Var/pushThreadBindings bindings))
+
+(defn pop-thread-bindings
+ "Pop one set of bindings pushed with push-binding before. It is an error to
+ pop bindings without pushing before."
+ []
+ (clojure.lang.Var/popThreadBindings))
+
+(defn get-thread-bindings
+ "Get a map with the Var/value pairs which is currently in effect for the
+ current thread."
+ []
+ (clojure.lang.Var/getThreadBindings))
+
(defmacro binding
"binding => var-symbol init-expr
@@ -1200,21 +1228,21 @@
are made in parallel (unlike let); all init-exprs are evaluated
before the vars are bound to their new values."
[bindings & body]
- (assert-args binding
- (vector? bindings) "a vector for its binding"
- (even? (count bindings)) "an even number of forms in binding vector")
- (let [var-ize (fn [var-vals]
- (loop [ret [] vvs (seq var-vals)]
- (if vvs
- (recur (conj (conj ret `(var ~(first vvs))) (second vvs))
- (next (next vvs)))
- (seq ret))))]
- `(let []
- (. clojure.lang.Var (pushThreadBindings (hash-map ~@(var-ize bindings))))
- (try
- ~@body
- (finally
- (. clojure.lang.Var (popThreadBindings)))))))
+ (assert-args binding
+ (vector? bindings) "a vector for its binding"
+ (even? (count bindings)) "an even number of forms in binding vector")
+ (let [var-ize (fn [var-vals]
+ (loop [ret [] vvs (seq var-vals)]
+ (if vvs
+ (recur (conj (conj ret `(var ~(first vvs))) (second vvs))
+ (next (next vvs)))
+ (seq ret))))]
+ `(let []
+ (push-thread-bindings (hash-map ~@(var-ize bindings)))
+ (try
+ ~@body
+ (finally
+ (pop-thread-bindings))))))
(defn find-var
"Returns the global var named by the namespace-qualified symbol, or