Skip to content

Commit

Permalink
Added bound-fn to define thread-local binding aware functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
kotarak authored and Chouser committed Nov 10, 2009
1 parent 9bde10d commit fbacc4a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/clj/clojure/core.clj
Expand Up @@ -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."
Expand Down
1 change: 1 addition & 0 deletions src/clj/clojure/main.clj
Expand Up @@ -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)))

Expand Down

0 comments on commit fbacc4a

Please sign in to comment.