diff options
author | Meikel Brandmeyer <mb@kotka.de> | 2009-08-08 22:57:29 +0200 |
---|---|---|
committer | Chouser <chouser@n01se.net> | 2009-11-10 10:42:12 -0500 |
commit | fbacc4a5751fa5c15baa599b5a058cd81b05a247 (patch) | |
tree | 59ccee8c1eb4d2c74a92a8b64ada985e99c1dd8a | |
parent | 9bde10da7b13dd24b5666260d231d79792a34305 (diff) |
Added bound-fn to define thread-local binding aware functions
bound-fn captures the thread-local bindings in effect where the
function is defined. Installs these bindings before executing the
body. This is useful for helper functions running in a different
thread.
Excluded with-bindings from clojure/main.clj to prevent name clash.
Fixes #170
Signed-off-by: Chouser <chouser@n01se.net>
-rw-r--r-- | src/clj/clojure/core.clj | 36 | ||||
-rw-r--r-- | src/clj/clojure/main.clj | 1 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 95402a00..2b66f6d0 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1253,6 +1253,42 @@ (finally (pop-thread-bindings)))))) +(defn with-bindings* + "Takes a map of Var/value pairs. Installs for the given Vars the associated + values as thread-local bindings. Then calls f with the supplied arguments. + Pops the installed bindings after f returned. Returns whatever f returns." + [binding-map f & args] + (push-thread-bindings binding-map) + (try + (apply f args) + (finally + (pop-thread-bindings)))) + +(defmacro with-bindings + "Takes a map of Var/value pairs. Installs for the given Vars the associated + values as thread-local bindings. The executes body. Pops the installed + bindings after body was evaluated. Returns the value of body." + [binding-map & body] + `(with-bindings* ~binding-map (fn [] ~@body))) + +(defn bound-fn* + "Returns a function, which will install the same bindings in effect as in + the thread at the time bound-fn* was called and then call f with any given + arguments. This may be used to define a helper function which runs on a + different thread, but needs the same bindings in place." + [f] + (let [bindings (get-thread-bindings)] + (fn [& args] + (apply with-bindings* bindings f args)))) + +(defmacro bound-fn + "Returns a function defined by the given fntail, which will install the + same bindings in effect as in the thread at the time bound-fn was called. + This may be used to define a helper function which runs on a different + thread, but needs the same bindings in place." + [& fntail] + `(bound-fn* (fn ~@fntail))) + (defn find-var "Returns the global var named by the namespace-qualified symbol, or nil if no var with that name." diff --git a/src/clj/clojure/main.clj b/src/clj/clojure/main.clj index 633c21e9..8c2e9449 100644 --- a/src/clj/clojure/main.clj +++ b/src/clj/clojure/main.clj @@ -9,6 +9,7 @@ ;; Originally contributed by Stephen C. Gilardi (ns clojure.main + (:refer-clojure :exclude [with-bindings]) (:import (clojure.lang Compiler Compiler$CompilerException LineNumberingPushbackReader RT))) |